11//! TFHE implementation of the Kreyvium Algorithm
22
33use crate :: shortint:: ciphertext:: NoiseLevel ;
4- use crate :: shortint:: { Ciphertext , ServerKey } ;
4+ use crate :: shortint:: oprf:: OprfSeed ;
5+ use crate :: shortint:: { Ciphertext , ClientKey , ServerKey } ;
6+ use crate :: transciphering:: backward_compatibility:: SerializableKreyviumFheKeyVersions ;
57use crate :: transciphering:: ciphers:: shift_register:: ShiftRegister ;
6- use crate :: transciphering:: { FheKeyStream , InsufficientKeystream , StreamCipherKind , Transcipherer } ;
8+ use crate :: transciphering:: {
9+ FheKeyStream , InsufficientKeystream , StreamCipherKind , Transcipherer , TranscipheringServerKey ,
10+ } ;
11+ use serde:: { Deserialize , Serialize } ;
12+ use tfhe_versionable:: Versionize ;
713
814use super :: {
9- collect_boxed_array, KreyviumBackwardRoundOutput , KreyviumIV , KreyviumRound ,
15+ collect_boxed_array, KreyviumBackwardRoundOutput , KreyviumIV , KreyviumPlainKey , KreyviumRound ,
1016 KreyviumRoundInput , KreyviumRoundOutput , KreyviumState ,
1117} ;
1218
1319/// A kreyvium key encrypted in LWE, one ciphertext per bit
20+ #[ derive( Clone , Serialize , Deserialize , Versionize ) ]
21+ #[ serde(
22+ into = "SerializableKreyviumFheKey" ,
23+ try_from = "SerializableKreyviumFheKey"
24+ ) ]
25+ #[ versionize(
26+ into = "SerializableKreyviumFheKey" ,
27+ try_from = "SerializableKreyviumFheKey"
28+ ) ]
1429pub struct KreyviumFheKey {
1530 cts : Box < [ Ciphertext ; 128 ] > ,
1631}
@@ -32,9 +47,72 @@ impl KreyviumFheKey {
3247 Self { cts }
3348 }
3449
50+ pub fn new_random (
51+ seed : impl OprfSeed ,
52+ transciphering_key : & TranscipheringServerKey ,
53+ sks : & ServerKey ,
54+ ) -> Self {
55+ let encrypted_bits = transciphering_key
56+ . oprf_key ( )
57+ . generate_random_boolean_sequence ( seed, 128 , sks) ;
58+
59+ let boxed: Box < [ Ciphertext ; 128 ] > = encrypted_bits
60+ . into_boxed_slice ( )
61+ . try_into ( )
62+ . expect ( "the vec has 128 elements" ) ;
63+
64+ Self :: new ( boxed)
65+ }
66+
3567 pub fn init_state ( self , iv : KreyviumIV , sk : & ServerKey ) -> KreyviumFheState {
3668 KreyviumFheState :: new ( self , iv, sk)
3769 }
70+
71+ /// Decrypt the key bits
72+ pub fn decrypt ( & self , client_key : & ClientKey ) -> KreyviumPlainKey {
73+ let mut decrypted_bits = [ false ; 128 ] ;
74+ for ( ct, out) in self . cts . iter ( ) . zip ( decrypted_bits. iter_mut ( ) ) {
75+ * out = client_key. decrypt ( ct) != 0 ;
76+ }
77+ KreyviumPlainKey :: from ( decrypted_bits)
78+ }
79+
80+ /// Borrow the underlying 128 single-bit shortint ciphertexts, MSB-first
81+ /// within each byte of the packed key (see [`super::KreyviumPlainKey`]).
82+ pub fn ciphertexts ( & self ) -> & [ Ciphertext ; 128 ] {
83+ & self . cts
84+ }
85+ }
86+
87+ /// Serialization form of [`KreyviumFheKey`]. The 128 key ciphertexts are stored
88+ /// in a `Vec` because serde/versionize don't support arrays longer than 32; the
89+ /// fixed-size array is restored on deserialization.
90+ #[ derive( Clone , Serialize , Deserialize , Versionize ) ]
91+ #[ versionize( SerializableKreyviumFheKeyVersions ) ]
92+ pub struct SerializableKreyviumFheKey {
93+ cts : Vec < Ciphertext > ,
94+ }
95+
96+ impl From < KreyviumFheKey > for SerializableKreyviumFheKey {
97+ fn from ( value : KreyviumFheKey ) -> Self {
98+ let cts: Box < [ Ciphertext ] > = value. cts ;
99+ Self {
100+ cts : cts. into_vec ( ) ,
101+ }
102+ }
103+ }
104+
105+ impl TryFrom < SerializableKreyviumFheKey > for KreyviumFheKey {
106+ type Error = crate :: Error ;
107+
108+ fn try_from ( value : SerializableKreyviumFheKey ) -> Result < Self , Self :: Error > {
109+ let len = value. cts . len ( ) ;
110+ let cts: Box < [ Ciphertext ; 128 ] > =
111+ value. cts . into_boxed_slice ( ) . try_into ( ) . map_err ( |_| {
112+ crate :: error!( "a kreyvium key must hold exactly 128 ciphertexts, got {len}" )
113+ } ) ?;
114+ Ok ( Self { cts } )
115+ }
38116}
39117
40118pub type KreyviumFheState = KreyviumState < Ciphertext > ;
0 commit comments