Implementation of fixed-base Edwards scalar multiplication in the circuit.

This commit is contained in:
Sean Bowe 2018-02-07 13:33:09 -07:00
parent 69833e5162
commit edc4adc32c
No known key found for this signature in database
GPG Key ID: 95684257D8F8B031
2 changed files with 106 additions and 2 deletions

View File

@ -17,7 +17,12 @@ use super::num::AllocatedNum;
use ::jubjub::{
JubjubEngine,
JubjubParams
JubjubParams,
FixedGenerators
};
use super::lookup::{
lookup3_xy
};
use super::boolean::Boolean;
@ -36,6 +41,56 @@ impl<E: Engine, Var: Copy> Clone for EdwardsPoint<E, Var> {
}
}
/// Perform a fixed-base scalar multiplication with
/// `by` being in little-endian bit order. `by` must
/// be a multiple of 3.
pub fn fixed_base_multiplication<E, Var, CS>(
mut cs: CS,
base: FixedGenerators,
by: &[Boolean<Var>],
params: &E::Params
) -> Result<EdwardsPoint<E, Var>, SynthesisError>
where CS: ConstraintSystem<E, Variable=Var>,
E: JubjubEngine,
Var: Copy
{
// We're going to chunk the scalar into 3-bit windows,
// so let's force the caller to supply the right number
// of bits for our lookups.
assert!(by.len() % 3 == 0);
// Represents the result of the multiplication
let mut result = None;
for (i, (chunk, window)) in by.chunks(3)
.zip(params.circuit_generators(base).iter())
.enumerate()
{
let (x, y) = lookup3_xy(
cs.namespace(|| format!("window table lookup {}", i)),
chunk,
window
)?;
let p = EdwardsPoint {
x: x,
y: y
};
if result.is_none() {
result = Some(p);
} else {
result = Some(result.unwrap().add(
cs.namespace(|| format!("addition {}", i)),
&p,
params
)?);
}
}
Ok(result.get()?.clone())
}
impl<E: JubjubEngine, Var: Copy> EdwardsPoint<E, Var> {
/// This extracts the x-coordinate, which is an injective
/// encoding for elements of the prime order subgroup.
@ -615,13 +670,16 @@ mod test {
use ::jubjub::{
montgomery,
edwards,
JubjubBls12
JubjubBls12,
JubjubParams,
FixedGenerators
};
use ::jubjub::fs::Fs;
use super::{
MontgomeryPoint,
EdwardsPoint,
AllocatedNum,
fixed_base_multiplication
};
use super::super::boolean::{
Boolean,
@ -731,6 +789,41 @@ mod test {
assert!(p.double(&mut cs, params).is_err());
}
#[test]
fn test_edwards_fixed_base_multiplication() {
let params = &JubjubBls12::new();
let rng = &mut XorShiftRng::from_seed([0x5dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]);
for _ in 0..100 {
let mut cs = TestConstraintSystem::<Bls12>::new();
let p = params.generator(FixedGenerators::NoteCommitmentRandomization);
let s = Fs::rand(rng);
let q = p.mul(s, params);
let (x1, y1) = q.into_xy();
let mut s_bits = BitIterator::new(s.into_repr()).collect::<Vec<_>>();
s_bits.reverse();
s_bits.truncate(Fs::NUM_BITS as usize);
let s_bits = s_bits.into_iter()
.enumerate()
.map(|(i, b)| AllocatedBit::alloc(cs.namespace(|| format!("scalar bit {}", i)), Some(b)).unwrap())
.map(|v| Boolean::from(v))
.collect::<Vec<_>>();
let q = fixed_base_multiplication(
cs.namespace(|| "multiplication"),
FixedGenerators::NoteCommitmentRandomization,
&s_bits,
params
).unwrap();
assert_eq!(q.x.get_value().unwrap(), x1);
assert_eq!(q.y.get_value().unwrap(), y1);
}
}
#[test]
fn test_edwards_multiplication() {
let params = &JubjubBls12::new();

View File

@ -49,6 +49,8 @@ pub trait JubjubParams<E: JubjubEngine>: Sized {
fn pedersen_circuit_generators(&self) -> &[Vec<Vec<(E::Fr, E::Fr)>>];
fn fixed_base_chunks_per_generator(&self) -> usize;
fn generator(&self, base: FixedGenerators) -> &edwards::Point<E, PrimeOrder>;
fn circuit_generators(&self, FixedGenerators) -> &[Vec<(E::Fr, E::Fr)>];
}
pub enum Unknown { }
@ -63,6 +65,7 @@ impl JubjubEngine for Bls12 {
/// Fixed generators of the Jubjub curve of unknown
/// exponent.
#[derive(Copy, Clone)]
pub enum FixedGenerators {
NoteCommitmentRandomization = 0,
Max = 1
@ -98,6 +101,14 @@ impl JubjubParams<Bls12> for JubjubBls12 {
fn pedersen_circuit_generators(&self) -> &[Vec<Vec<(Fr, Fr)>>] {
&self.pedersen_circuit_generators
}
fn generator(&self, base: FixedGenerators) -> &edwards::Point<Bls12, PrimeOrder>
{
&self.fixed_base_generators[base as usize]
}
fn circuit_generators(&self, base: FixedGenerators) -> &[Vec<(Fr, Fr)>]
{
&self.fixed_base_circuit_generators[base as usize][..]
}
}
impl JubjubBls12 {