-
Notifications
You must be signed in to change notification settings - Fork 151
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* schnorr signature draft * record hash update code * refactor function signature * clean up * add test for schnorr signature * update comment * implement even check * update test * fix a bug * update test * nit * resolve comments * resolve comments * nits * nits
- Loading branch information
1 parent
f2eacb1
commit 5de49cf
Showing
9 changed files
with
501 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
{"strategy":"Simple","degree":19,"num_advice":1,"num_lookup_advice":1,"num_fixed":1,"lookup_bits":18,"limb_bits":88,"num_limbs":3} | ||
{"strategy":"Simple","degree":18,"num_advice":2,"num_lookup_advice":1,"num_fixed":1,"lookup_bits":17,"limb_bits":88,"num_limbs":3} | ||
{"strategy":"Simple","degree":17,"num_advice":4,"num_lookup_advice":1,"num_fixed":1,"lookup_bits":16,"limb_bits":88,"num_limbs":3} | ||
{"strategy":"Simple","degree":16,"num_advice":8,"num_lookup_advice":2,"num_fixed":1,"lookup_bits":15,"limb_bits":90,"num_limbs":3} | ||
{"strategy":"Simple","degree":15,"num_advice":17,"num_lookup_advice":3,"num_fixed":1,"lookup_bits":14,"limb_bits":90,"num_limbs":3} | ||
{"strategy":"Simple","degree":14,"num_advice":34,"num_lookup_advice":6,"num_fixed":1,"lookup_bits":13,"limb_bits":91,"num_limbs":3} | ||
{"strategy":"Simple","degree":13,"num_advice":68,"num_lookup_advice":12,"num_fixed":1,"lookup_bits":12,"limb_bits":88,"num_limbs":3} | ||
{"strategy":"Simple","degree":12,"num_advice":139,"num_lookup_advice":24,"num_fixed":2,"lookup_bits":11,"limb_bits":88,"num_limbs":3} | ||
{"strategy":"Simple","degree":11,"num_advice":291,"num_lookup_advice":53,"num_fixed":4,"lookup_bits":10,"limb_bits":88,"num_limbs":3} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
{"strategy":"Simple","degree":18,"num_advice":2,"num_lookup_advice":1,"num_fixed":1,"lookup_bits":17,"limb_bits":88,"num_limbs":3} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
use super::OverflowInteger; | ||
use halo2_base::gates::GateInstructions; | ||
use halo2_base::gates::RangeChip; | ||
use halo2_base::{safe_types::RangeInstructions, utils::ScalarField, AssignedValue, Context}; | ||
|
||
/// # Assumptions | ||
/// * `a` has nonzero number of limbs | ||
pub fn positive<F: ScalarField>( | ||
range: &RangeChip<F>, | ||
ctx: &mut Context<F>, | ||
a: OverflowInteger<F>, | ||
limb_bits: usize, | ||
) -> AssignedValue<F> { | ||
let k = a.limbs.len(); | ||
assert_ne!(k, 0); | ||
let first_cell: AssignedValue<F> = a.limbs[0]; | ||
|
||
let last_bit = range.get_last_bit(ctx, first_cell, limb_bits); | ||
range.gate.not(ctx, last_bit) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
use crate::bigint::{big_is_equal, ProperCrtUint}; | ||
use crate::fields::{fp::FpChip, FieldChip, PrimeField}; | ||
use halo2_base::{gates::GateInstructions, utils::CurveAffineExt, AssignedValue, Context}; | ||
|
||
use super::{fixed_base, scalar_multiply, EcPoint, EccChip}; | ||
|
||
// CF is the coordinate field of GA | ||
// SF is the scalar field of GA | ||
// p = base field modulus | ||
// n = scalar field modulus | ||
// checks r < p, 0 < s < n, 0 < msgHash < n | ||
// this circuit applies over constraints that s > 0, msgHash > 0 cause scalar_multiply can't handle zero scalar | ||
/// `pubkey` should not be the identity point | ||
/// follow spec in https://github.com/bitcoin/bips/blob/master/bip-0340.mediawiki | ||
pub fn schnorr_verify_no_pubkey_check<F: PrimeField, CF: PrimeField, SF: PrimeField, GA>( | ||
chip: &EccChip<F, FpChip<F, CF>>, | ||
ctx: &mut Context<F>, | ||
pubkey: EcPoint<F, <FpChip<F, CF> as FieldChip<F>>::FieldPoint>, | ||
r: ProperCrtUint<F>, // int(sig[0:32]); fail if r ≥ p. | ||
s: ProperCrtUint<F>, // int(sig[32:64]); fail if s ≥ n | ||
msgHash: ProperCrtUint<F>, // int(hashBIP0340/challenge(bytes(r) || bytes(P) || m)) mod n | ||
var_window_bits: usize, | ||
fixed_window_bits: usize, | ||
) -> AssignedValue<F> | ||
where | ||
GA: CurveAffineExt<Base = CF, ScalarExt = SF>, | ||
{ | ||
let base_chip = chip.field_chip; | ||
let scalar_chip = | ||
FpChip::<F, SF>::new(base_chip.range, base_chip.limb_bits, base_chip.num_limbs); | ||
|
||
// check r < p | ||
let r_valid = base_chip.is_less_than_p(ctx, &r); | ||
// check 0 < s < n | ||
let s_valid = scalar_chip.is_soft_nonzero(ctx, &s); | ||
// check 0 < e < n | ||
let e_valid = scalar_chip.is_soft_nonzero(ctx, &msgHash); | ||
|
||
// compute s * G and msgHash * pubkey | ||
let s_G = fixed_base::scalar_multiply( | ||
base_chip, | ||
ctx, | ||
&GA::generator(), | ||
s.limbs().to_vec(), | ||
base_chip.limb_bits, | ||
fixed_window_bits, | ||
); | ||
let e_P = scalar_multiply::<_, _, GA>( | ||
base_chip, | ||
ctx, | ||
pubkey, | ||
msgHash.limbs().to_vec(), | ||
base_chip.limb_bits, | ||
var_window_bits, | ||
); | ||
|
||
// check s_G.x != e_P.x, which is a requirement for sub_unequal | ||
let x_eq = base_chip.is_equal(ctx, &s_G.x, &e_P.x); | ||
let x_neq = base_chip.gate().not(ctx, x_eq); | ||
|
||
// R = s⋅G - e⋅P | ||
// R is not infinity point implicitly constrainted by is_strict = true | ||
let R = chip.sub_unequal(ctx, s_G, e_P, true); | ||
|
||
// check R.y is even | ||
let R_y = R.y; | ||
let R_y_is_even: AssignedValue<F> = base_chip.is_even(ctx, &R_y); | ||
|
||
// check R.x == r | ||
let R_x = scalar_chip.enforce_less_than(ctx, R.x); | ||
let equal_check = big_is_equal::assign(base_chip.gate(), ctx, R_x.0, r); | ||
|
||
let res1 = base_chip.gate().and(ctx, r_valid, s_valid); | ||
let res2: AssignedValue<F> = base_chip.gate().and(ctx, res1, e_valid); | ||
let res3 = base_chip.gate().and(ctx, res2, x_neq); | ||
let res4: AssignedValue<F> = base_chip.gate().and(ctx, res3, R_y_is_even); | ||
let res5 = base_chip.gate().and(ctx, res4, equal_check); | ||
|
||
res5 | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.