Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rho=4096 #3

Draft
wants to merge 8 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
Synchronized multi-signature scheme from lattice
------

This is a reference implementation for the paper: [Synchronized multi-signature scheme from lattice](tbd).
This is a reference implementation for the paper: [Squirrel: Efficient Synchronized Multi-Signatures from Lattices](https://eprint.iacr.org/2022/694).

# Benchmark
```
Expand Down
2 changes: 1 addition & 1 deletion bench.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ Parameters and benchmark results

# rho = 1024; rho = 21

- q_hvc = 12289
- q_hvc = 61441
- q_hots = 6694913
- alpha = 20
- beta_s = 44
Expand Down
34 changes: 18 additions & 16 deletions benches/bench.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,28 +23,29 @@ fn smsig() {
rng.fill_bytes(&mut seed);

let start = Instant::now();
for _ in 0..NUM_REPETITIONS {
let _ = SMSigScheme::key_gen(&seed, &pp);
}
// for _ in 0..NUM_REPETITIONS {
// let _ = SMSigScheme::key_gen(&seed, &pp);
// }

let (pk, sk) = SMSigScheme::key_gen(&seed, &pp);
println!(
"ken gen time {}",
start.elapsed().as_nanos() / NUM_REPETITIONS as u128
);
let (pk, sk) = SMSigScheme::key_gen(&seed, &pp);

// ===============================
// sign
// ===============================
let start = Instant::now();
for _ in 0..NUM_REPETITIONS {
let _ = SMSigScheme::sign(&sk, 0, message.as_ref(), &pp);
}

// for _ in 0..NUM_REPETITIONS {
// let _ = SMSigScheme::sign(&sk, 0, message.as_ref(), &pp);
// }
let sig = SMSigScheme::sign(&sk, 0, message.as_ref(), &pp);
println!(
"signing time {}",
start.elapsed().as_nanos() / NUM_REPETITIONS as u128
);
let sig = SMSigScheme::sign(&sk, 0, message.as_ref(), &pp);


// ===============================
// verify
Expand All @@ -60,33 +61,34 @@ fn smsig() {

let mut sigs = Vec::new();
let mut pks = Vec::new();
for _ in 0..1000 {
for _ in 0..4096 {
pks.push(pk);
sigs.push(sig.clone());
}
// ===============================
// aggregation
// ===============================
let start = Instant::now();
for _ in 0..NUM_REPETITIONS {
SMSigScheme::aggregate(&sigs, &pks);
}
// for _ in 0..NUM_REPETITIONS {
// SMSigScheme::aggregate(&sigs, &pks);
// }

let agg_sig = SMSigScheme::aggregate(&sigs, &pks);
println!(
"aggregating time {}",
start.elapsed().as_nanos() / NUM_REPETITIONS as u128
);
let agg_sig = SMSigScheme::aggregate(&sigs, &pks);
// ===============================
// batch verification
// ===============================
let start = Instant::now();
for _ in 0..NUM_REPETITIONS {
assert!(SMSigScheme::batch_verify(
SMSigScheme::batch_verify(
&pks,
message.as_ref(),
&agg_sig,
&pp
));
);
}
println!(
"batch verification {}",
Expand Down
6 changes: 3 additions & 3 deletions benches/bench_.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use rand_chacha::ChaCha20Rng;
use sync_multi_sig::{
HOTSHash, HVCHash, LargeNTTPoly, LargePoly, MultiSig, Path, RandomizedPath, Randomizers,
SMSigScheme, SignedPoly, SmallNTTPoly, SmallPoly, TerPolyCoeffEncoding, Tree, ALPHA, HEIGHT,
SMALL_MODULUS_BITS,
SMALL_MODULUS_BITS, LARGE_MODULUS_BITS,
};

criterion_main!(bench);
Expand Down Expand Up @@ -160,7 +160,7 @@ fn bench_hash(c: &mut Criterion) {
let num_tests = 1000;
let hasher = HVCHash::init(&mut rng);
let inputs: Vec<Vec<SmallPoly>> = (0..num_tests)
.map(|_| (0..28).map(|_| SmallPoly::rand_poly(&mut rng)).collect())
.map(|_| (0..SMALL_MODULUS_BITS<<1).map(|_| SmallPoly::rand_poly(&mut rng)).collect())
.collect();

let mut bench_group = c.benchmark_group("hash");
Expand All @@ -176,7 +176,7 @@ fn bench_hash(c: &mut Criterion) {

let hasher = HOTSHash::init(&mut rng);
let inputs: Vec<Vec<SignedPoly>> = (0..num_tests)
.map(|_| (0..46).map(|_| SignedPoly::rand_binary(&mut rng)).collect())
.map(|_| (0..LARGE_MODULUS_BITS<<1).map(|_| SignedPoly::rand_binary(&mut rng)).collect())
.collect();
let bench_str = format!("{} hots_hash digests", num_tests);
bench_group.bench_function(bench_str, move |b| {
Expand Down
566 changes: 302 additions & 264 deletions cpoly/c/hots_ntt.c

Large diffs are not rendered by default.

401 changes: 200 additions & 201 deletions cpoly/c/hvc_ntt.c

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion cpoly/c/params.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,6 @@

#define SEEDBYTES 32
#define N 512
#define HVC_Q 12289
#define HVC_Q 61441

#endif
4 changes: 2 additions & 2 deletions cpoly/c/test.c
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ int test_hvc_ntt() {
for (i = 0; i < NTESTS; ++i) {
// a is a random poly
for (j = 0; j < N; j++) {
a[j] = rand() % 12289;
a[j] = rand() % 61441;
a_rec[j] = a[j];
}

Expand Down Expand Up @@ -136,7 +136,7 @@ int test_hots_ntt() {
for (i = 0; i < NTESTS; ++i) {
// a is a random poly
for (j = 0; j < N; j++) {
a[j] = rand() % 0x662801;
a[j] = rand() % 28930049;
a_rec[j] = a[j];
}

Expand Down
2 changes: 1 addition & 1 deletion cpoly/src/bindings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ pub const __have_pthread_attr_t: u32 = 1;
pub const _ALLOCA_H: u32 = 1;
pub const SEEDBYTES: u32 = 32;
pub const N: u32 = 512;
pub const HVC_Q: u32 = 12289;
pub const HVC_Q: u32 = 61441;
pub type __u_char = ::std::os::raw::c_uchar;
pub type __u_short = ::std::os::raw::c_ushort;
pub type __u_int = ::std::os::raw::c_uint;
Expand Down
2 changes: 1 addition & 1 deletion scripts/hash.sage
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
Q = 12289
Q = 61441
P.<x> = PolynomialRing(Zmod(Q))

left = [586, 10792, 95, 1371, 9037, 8688, 5241, 8794, 2081, 11816, 11706, 3616, 994, 1111, 4947, 7830, 10448, 1941, 3066, 4, 4902, 15, 10081, 7055, 11939, 2994, 11275, 6273, 6441, 2632, 5185, 7564, 9383, 2121, 8508, 4639, 8468, 1892, 6769, 11963, 863, 785, 3135, 4965, 9263, 1176, 10213, 5693, 7630, 10983, 7315, 1587, 9553, 8659, 5234, 11153, 7162, 7733, 6185, 10252, 12097, 3605, 5866, 363, 468, 7114, 7483, 8606, 8438, 1560, 8598, 7748, 11952, 2741, 6861, 2203, 5414, 5220, 4534, 8939, 1216, 3149, 6382, 11247, 766, 1862, 9079, 811, 8949, 3642, 11847, 3986, 3077, 5341, 10353, 1951, 4584, 7246, 10292, 3456, 10571, 3759, 1020, 1107, 258, 9301, 3314, 568, 4647, 5636, 1174, 9646, 9343, 2645, 9551, 5446, 10050, 9665, 10688, 3726, 2368, 1701, 4003, 2440, 11785, 3905, 2112, 9428, 4293, 6024, 3020, 5778, 9628, 6689, 2805, 4295, 2995, 5473, 5374, 9441, 8782, 10725, 3864, 7777, 4282, 12201, 5549, 3053, 1969, 2494, 6100, 2046, 4280, 2594, 8417, 12244, 4563, 5868, 6094, 1051, 10747, 10897, 572, 11668, 2151, 6406, 906, 4008, 2982, 8909, 7968, 3535, 2339, 10370, 7911, 6887, 192, 11999, 5506, 8589, 11651, 9266, 7795, 3343, 7630, 10935, 4591, 12185, 8914, 2716, 6336, 9247, 8952, 8721, 6683, 4749, 402, 2094, 1899, 10569, 1821, 1668, 2279, 1005, 11935, 3477, 10791, 5909, 121, 2900, 8129, 4672, 2186, 7225, 9159, 5673, 37, 2415, 9042, 3140, 3164, 8533, 10834, 1985, 2889, 9923, 2198, 8225, 2808, 10266, 8790, 10936, 2130, 9307, 591, 7942, 1177, 127, 9209, 1796, 9150, 6776, 12072, 5250, 2710, 4736, 5510, 5211, 10241, 4097, 3872, 1778, 8311, 8721, 3844, 6389]
Expand Down
31 changes: 20 additions & 11 deletions scripts/roots.sage
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,10 @@ def reverse_bits(i, n):
return res

def print_hots_ntt():
q_hots = 0x662801
# while q_hots%4096!=1:
# q_hots = next_prime(q_hots)
q_hots = 28930049
while q_hots%4096!=1:
q_hots = next_prime(q_hots)
print(q_hots)

P.<x> = PolynomialRing(Zmod(q_hots))
f = P(x^1024+1)
Expand All @@ -35,25 +36,29 @@ def print_hots_ntt():
print()

def print_hots_inv_ntt():
q_hots = 0x662801
# while q_hots%4096!=1:
# q_hots = next_prime(q_hots)
q_hots = 28930049
while q_hots%4096!=1:
q_hots = next_prime(q_hots)

P.<x> = PolynomialRing(Zmod(q_hots))
f = P(x^1024+1)
r = f.roots()[0][0]
r_inv = 1/r
print(r)
print(r_inv)

for i in range (1024):
e = reverse_bits(ZZ(i), 10)
print(r_inv^e, end = ', ')
print()

def print_hvc_ntt():
q_hvc = 12289
r = Zmod(q_hvc)(7)
q_hvc = 61441
# r = Zmod(q_hvc)(61)
P.<x> = PolynomialRing(Zmod(q_hvc))
f = P(x^1024+1)
r = f.roots()[0][0]
r_inv = 1/r
print(r)

for i in range (1024):
e = reverse_bits(ZZ(i), 10)
Expand All @@ -62,9 +67,13 @@ def print_hvc_ntt():
print()

def print_hvc_inv_ntt():
q_hvc = 12289
r = Zmod(q_hvc)(7)
q_hvc = 61441
# r = Zmod(q_hvc)(61)
P.<x> = PolynomialRing(Zmod(q_hvc))
f = P(x^1024+1)
r = f.roots()[0][0]
r_inv = 1/r
print(r_inv)

for i in range (1024):
e = reverse_bits(ZZ(i), 10)
Expand Down
2 changes: 2 additions & 0 deletions src/hots/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,8 @@ impl HomomorphicOneTimeSignature for HOTS {
left += a * LargeNTTPoly::from(s)
}
let right = hm * LargeNTTPoly::from(&pk.v0) + LargeNTTPoly::from(&pk.v1);
// println!("left {:?}", left);
// println!("right {:?}", right);
left == right
}

Expand Down
14 changes: 7 additions & 7 deletions src/param.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,28 +5,28 @@ pub const N: usize = 512;
pub const ALPHA: usize = 20;

// q for small ring, HVC modulus
pub const SMALL_MODULUS: u16 = 12289;
pub const SMALL_MODULUS: u16 = 61441;

// log(q) for HVC modulus
pub const SMALL_MODULUS_BITS: usize = 14;
pub const SMALL_MODULUS_BITS: usize = 16;

// the largest multiple of q that is smaller than 2^32
pub const SMALL_SAMPLE_THRESHOLD: u32 = 4294956344;
pub const SMALL_SAMPLE_THRESHOLD: u32 = 4294910223;

// height of the tree for the HVC scheme
pub const HEIGHT: usize = 21;

// q for the larger ring, HOTS modulus
pub const LARGE_MODULUS: u32 = 0x662801;
pub const LARGE_MODULUS: u32 = 28930049;

// the largest multiple of q that is smaller than 2^32
pub const LARGE_SAMPLE_THRESHOLD: u32 = 4291439233;
pub const LARGE_SAMPLE_THRESHOLD: u32 = 4281647252;

// log(q) for HOTS modulus
pub(crate) const LARGE_MODULUS_BITS: usize = 23;
pub const LARGE_MODULUS_BITS: usize = 25;

// dimension of secret keys in OTS
pub(crate) const GAMMA: usize = 41;
pub(crate) const GAMMA: usize = 44;

// norm bound for second component of HOTS secret key
// Also the number of non-zero entries for hash of message
Expand Down
4 changes: 2 additions & 2 deletions src/poly/large_poly.rs
Original file line number Diff line number Diff line change
Expand Up @@ -172,14 +172,14 @@ impl Default for LargeNTTPoly {
}

impl From<&SignedPoly> for LargeNTTPoly {
// convert poly into its ntt form. Requires that coefficients are between 0 and 12289
// convert poly into its ntt form. Requires that coefficients are between 0 and 61441
fn from(poly: &SignedPoly) -> Self {
(&LargePoly::from(poly)).into()
}
}

impl From<&LargePoly> for LargeNTTPoly {
// convert poly into its ntt form. Requires that coefficients are between 0 and 12289
// convert poly into its ntt form. Requires that coefficients are between 0 and 61441
fn from(poly: &LargePoly) -> Self {
let mut coeffs = poly.coeffs;
unsafe {
Expand Down
6 changes: 3 additions & 3 deletions src/poly/signed_poly.rs
Original file line number Diff line number Diff line change
Expand Up @@ -90,15 +90,15 @@ impl SignedPoly {
// slow. only used for correctness checking
#[cfg(test)]
pub(crate) fn schoolbook(a: &Self, b: &Self, q: i32) -> Self {
let mut buf = [0i32; N * 2];
let mut buf = [0i64; N * 2];
let mut c = [0; N];
for i in 0..N {
for j in 0..N {
buf[i + j] += a.coeffs[i] * b.coeffs[j] % q;
buf[i + j] += a.coeffs[i] as i64 * b.coeffs[j] as i64 % q as i64;
}
}
for i in 0..N {
c[i] = (buf[i] - buf[i + N]) % q;
c[i] = ((buf[i] - buf[i + N]) % q as i64) as i32;
}
Self { coeffs: c }
}
Expand Down
18 changes: 9 additions & 9 deletions src/poly/small_poly.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ impl AddAssign for SmallPoly {
self.coeffs
.iter_mut()
.zip(other.coeffs)
.for_each(|(x, y)| *x = (*x + y) % MODULUS)
.for_each(|(x, y)| *x = ((*x as u32 + y as u32) % MODULUS as u32) as u16)
}
}

Expand All @@ -88,15 +88,15 @@ impl SmallPoly {
// slow. only used for correctness checking
#[cfg(test)]
pub(crate) fn schoolbook(a: &Self, b: &Self) -> Self {
let mut buf = [0i32; N * 2];
let mut buf = [0i64; N * 2];
let mut c = [0; N];
for i in 0..N {
for j in 0..N {
buf[i + j] += (a.coeffs[i] as i32) * (b.coeffs[j] as i32) % (MODULUS as i32);
buf[i + j] += (a.coeffs[i] as i64) * (b.coeffs[j] as i64) % (MODULUS as i64);
}
}
for i in 0..N {
c[i] = lift(buf[i] - buf[i + N]);
c[i] = lift(((buf[i] - buf[i + N]) % MODULUS as i64) as i32);
}
Self { coeffs: c }
}
Expand Down Expand Up @@ -172,14 +172,14 @@ impl Default for SmallNTTPoly {
}

impl From<&SignedPoly> for SmallNTTPoly {
// convert poly into its ntt form. Requires that coefficients are between 0 and 12289
// convert poly into its ntt form. Requires that coefficients are between 0 and 61441
fn from(poly: &SignedPoly) -> Self {
(&SmallPoly::from(poly)).into()
}
}

impl From<&SmallPoly> for SmallNTTPoly {
// convert poly into its ntt form. Requires that coefficients are between 0 and 12289
// convert poly into its ntt form. Requires that coefficients are between 0 and 61441
fn from(poly: &SmallPoly) -> Self {
let mut coeffs = poly.coeffs;
unsafe {
Expand Down Expand Up @@ -209,7 +209,7 @@ impl Add for SmallNTTPoly {
.iter_mut()
.zip(self.coeffs.iter().zip(other.coeffs.iter()))
{
*e = (f + g) % MODULUS
*e = ((*f as u32 + *g as u32) % MODULUS as u32) as u16
}

res
Expand All @@ -219,7 +219,7 @@ impl Add for SmallNTTPoly {
impl AddAssign for SmallNTTPoly {
fn add_assign(&mut self, other: SmallNTTPoly) {
for (x, y) in self.coeffs.iter_mut().zip(other.coeffs) {
*x = (*x + y) % MODULUS
*x = ((*x as u32 + y as u32) % MODULUS as u32) as u16
}
}
}
Expand All @@ -243,7 +243,7 @@ impl Mul for SmallNTTPoly {
}

fn lift(a: i32) -> u16 {
(a % MODULUS as i32 + MODULUS as i32) as u16 % MODULUS
((a % MODULUS as i32 + MODULUS as i32) % MODULUS as i32) as u16
}

#[cfg(test)]
Expand Down
Loading