@@ -2,3 +2,171 @@ pub mod digits_to_int;
22pub mod encoding;
33pub mod public_key;
44pub mod sampler;
5+
6+ #[ cfg( test) ]
7+ mod tests {
8+ use crate :: {
9+ bgg:: sampler:: { BGGEncodingSampler , BGGPublicKeySampler } ,
10+ matrix:: { PolyMatrix , dcrt_poly:: DCRTPolyMatrix } ,
11+ poly:: {
12+ Poly , PolyParams ,
13+ dcrt:: { params:: DCRTPolyParams , poly:: DCRTPoly } ,
14+ } ,
15+ sampler:: { PolyUniformSampler , hash:: DCRTPolyHashSampler , uniform:: DCRTPolyUniformSampler } ,
16+ utils:: { create_bit_random_poly, create_random_poly} ,
17+ } ;
18+ use keccak_asm:: Keccak256 ;
19+
20+ #[ test]
21+ fn test_bgg_pub_key_addition ( ) {
22+ let key: [ u8 ; 32 ] = rand:: random ( ) ;
23+ let tag: u64 = rand:: random ( ) ;
24+ let tag_bytes = tag. to_le_bytes ( ) ;
25+ let params = DCRTPolyParams :: default ( ) ;
26+ let packed_input_size = 2 ;
27+ let d = 3 ;
28+ let bgg_sampler = BGGPublicKeySampler :: < _ , DCRTPolyHashSampler < Keccak256 > > :: new ( key, d) ;
29+ let reveal_plaintexts = vec ! [ true ; packed_input_size] ;
30+ let sampled_pub_keys = bgg_sampler. sample ( & params, & tag_bytes, & reveal_plaintexts) ;
31+ let log_base_q = params. modulus_digits ( ) ;
32+ let columns = ( d + 1 ) * log_base_q;
33+
34+ for pair in sampled_pub_keys[ 1 ..] . chunks ( 2 ) {
35+ if let [ a, b] = pair {
36+ let addition = a. clone ( ) + b. clone ( ) ;
37+ assert_eq ! ( addition. matrix. row_size( ) , d + 1 ) ;
38+ assert_eq ! ( addition. matrix. col_size( ) , columns) ;
39+ assert_eq ! ( addition. matrix, a. matrix. clone( ) + b. matrix. clone( ) ) ;
40+ }
41+ }
42+ }
43+
44+ #[ test]
45+ fn test_bgg_pub_key_multiplication ( ) {
46+ let key: [ u8 ; 32 ] = rand:: random ( ) ;
47+ let tag: u64 = rand:: random ( ) ;
48+ let tag_bytes = tag. to_le_bytes ( ) ;
49+ let params = DCRTPolyParams :: default ( ) ;
50+ let packed_input_size = 2 ;
51+ let d = 3 ;
52+ let bgg_sampler = BGGPublicKeySampler :: < _ , DCRTPolyHashSampler < Keccak256 > > :: new ( key, d) ;
53+ let reveal_plaintexts = vec ! [ true ; packed_input_size] ;
54+ let sampled_pub_keys = bgg_sampler. sample ( & params, & tag_bytes, & reveal_plaintexts) ;
55+ let log_base_q = params. modulus_digits ( ) ;
56+ let columns = ( d + 1 ) * log_base_q;
57+
58+ for pair in sampled_pub_keys[ 1 ..] . chunks ( 2 ) {
59+ if let [ a, b] = pair {
60+ let multiplication = a. clone ( ) * b. clone ( ) ;
61+ assert_eq ! ( multiplication. matrix. row_size( ) , d + 1 ) ;
62+ assert_eq ! ( multiplication. matrix. col_size( ) , columns) ;
63+ assert_eq ! ( multiplication. matrix, ( a. matrix. clone( ) * b. matrix. decompose( ) . clone( ) ) )
64+ }
65+ }
66+ }
67+
68+ #[ test]
69+ fn test_bgg_encoding_sampling ( ) {
70+ let input_size = 10_usize ;
71+ let key: [ u8 ; 32 ] = rand:: random ( ) ;
72+ let tag: u64 = rand:: random ( ) ;
73+ let tag_bytes = tag. to_le_bytes ( ) ;
74+ let params = DCRTPolyParams :: default ( ) ;
75+ let packed_input_size = input_size. div_ceil ( params. ring_dimension ( ) . try_into ( ) . unwrap ( ) ) ;
76+ let d = 3 ;
77+ let bgg_sampler = BGGPublicKeySampler :: < _ , DCRTPolyHashSampler < Keccak256 > > :: new ( key, d) ;
78+ let reveal_plaintexts = vec ! [ true ; packed_input_size + 1 ] ;
79+ let sampled_pub_keys = bgg_sampler. sample ( & params, & tag_bytes, & reveal_plaintexts) ;
80+ let uniform_sampler = DCRTPolyUniformSampler :: new ( ) ;
81+ let secrets = vec ! [ create_bit_random_poly( & params) ; d] ;
82+ let plaintexts = vec ! [ DCRTPoly :: const_one( & params) ; packed_input_size] ;
83+ let bgg_sampler = BGGEncodingSampler :: new ( & params, & secrets, uniform_sampler, 0.0 ) ;
84+ let bgg_encodings = bgg_sampler. sample ( & params, & sampled_pub_keys, & plaintexts) ;
85+ let g = DCRTPolyMatrix :: gadget_matrix ( & params, d + 1 ) ;
86+ assert_eq ! ( bgg_encodings. len( ) , packed_input_size + 1 ) ;
87+ assert_eq ! (
88+ bgg_encodings[ 0 ] . vector,
89+ bgg_sampler. secret_vec. clone( ) * bgg_encodings[ 0 ] . pubkey. matrix. clone( ) -
90+ bgg_sampler. secret_vec. clone( ) *
91+ ( g. clone( ) * bgg_encodings[ 0 ] . plaintext. clone( ) . unwrap( ) )
92+ ) ;
93+ assert_eq ! (
94+ bgg_encodings[ 1 ] . vector,
95+ bgg_sampler. secret_vec. clone( ) * bgg_encodings[ 1 ] . pubkey. matrix. clone( ) -
96+ bgg_sampler. secret_vec. clone( ) *
97+ ( g * bgg_encodings[ 1 ] . plaintext. clone( ) . unwrap( ) )
98+ )
99+ }
100+
101+ #[ test]
102+ fn test_bgg_encoding_addition ( ) {
103+ let key: [ u8 ; 32 ] = rand:: random ( ) ;
104+ let tag: u64 = rand:: random ( ) ;
105+ let tag_bytes = tag. to_le_bytes ( ) ;
106+ let params = DCRTPolyParams :: default ( ) ;
107+ let packed_input_size = 2 ;
108+ let d = 3 ;
109+ let bgg_sampler = BGGPublicKeySampler :: < _ , DCRTPolyHashSampler < Keccak256 > > :: new ( key, d) ;
110+ let reveal_plaintexts = vec ! [ true ; packed_input_size + 1 ] ;
111+ let sampled_pub_keys = bgg_sampler. sample ( & params, & tag_bytes, & reveal_plaintexts) ;
112+ let uniform_sampler = DCRTPolyUniformSampler :: new ( ) ;
113+ let secrets = vec ! [ create_bit_random_poly( & params) ; d] ;
114+ let plaintexts = vec ! [ create_random_poly( & params) ; packed_input_size] ;
115+ // TODO: set the standard deviation to a non-zero value
116+ let bgg_sampler = BGGEncodingSampler :: new ( & params, & secrets, uniform_sampler, 0.0 ) ;
117+ let bgg_encodings = bgg_sampler. sample ( & params, & sampled_pub_keys, & plaintexts) ;
118+
119+ for pair in bgg_encodings[ 1 ..] . chunks ( 2 ) {
120+ if let [ a, b] = pair {
121+ let addition = a. clone ( ) + b. clone ( ) ;
122+ assert_eq ! ( addition. pubkey, a. pubkey. clone( ) + b. pubkey. clone( ) ) ;
123+ assert_eq ! (
124+ addition. clone( ) . plaintext. unwrap( ) ,
125+ a. plaintext. clone( ) . unwrap( ) + b. plaintext. clone( ) . unwrap( )
126+ ) ;
127+ let g = DCRTPolyMatrix :: gadget_matrix ( & params, d + 1 ) ;
128+ assert_eq ! ( addition. vector, a. clone( ) . vector + b. clone( ) . vector) ;
129+ assert_eq ! (
130+ addition. vector,
131+ bgg_sampler. secret_vec. clone( ) *
132+ ( addition. pubkey. matrix - ( g * addition. plaintext. unwrap( ) ) )
133+ )
134+ }
135+ }
136+ }
137+
138+ #[ test]
139+ fn test_bgg_encoding_multiplication ( ) {
140+ let key: [ u8 ; 32 ] = rand:: random ( ) ;
141+ let tag: u64 = rand:: random ( ) ;
142+ let tag_bytes = tag. to_le_bytes ( ) ;
143+ let params = DCRTPolyParams :: default ( ) ;
144+ let packed_input_size = 2 ;
145+ let d = 3 ;
146+ let bgg_sampler = BGGPublicKeySampler :: < _ , DCRTPolyHashSampler < Keccak256 > > :: new ( key, d) ;
147+ let reveal_plaintexts = vec ! [ true ; packed_input_size + 1 ] ;
148+ let sampled_pub_keys = bgg_sampler. sample ( & params, & tag_bytes, & reveal_plaintexts) ;
149+ let uniform_sampler = DCRTPolyUniformSampler :: new ( ) ;
150+ let secrets = vec ! [ create_bit_random_poly( & params) ; d] ;
151+ let plaintexts = vec ! [ create_random_poly( & params) ; packed_input_size] ;
152+ let bgg_sampler = BGGEncodingSampler :: new ( & params, & secrets, uniform_sampler, 0.0 ) ;
153+ let bgg_encodings = bgg_sampler. sample ( & params, & sampled_pub_keys, & plaintexts) ;
154+
155+ for pair in bgg_encodings[ 1 ..] . chunks ( 2 ) {
156+ if let [ a, b] = pair {
157+ let multiplication = a. clone ( ) * b. clone ( ) ;
158+ assert_eq ! ( multiplication. pubkey, ( a. clone( ) . pubkey * b. clone( ) . pubkey) ) ;
159+ assert_eq ! (
160+ multiplication. clone( ) . plaintext. unwrap( ) ,
161+ a. clone( ) . plaintext. unwrap( ) * b. clone( ) . plaintext. unwrap( )
162+ ) ;
163+ let g = DCRTPolyMatrix :: gadget_matrix ( & params, d + 1 ) ;
164+ assert_eq ! (
165+ multiplication. vector,
166+ ( bgg_sampler. secret_vec. clone( ) *
167+ ( multiplication. pubkey. matrix - ( g * multiplication. plaintext. unwrap( ) ) ) )
168+ )
169+ }
170+ }
171+ }
172+ }
0 commit comments