Swap bit-endianness of value in note commitment.

This commit is contained in:
Sean Bowe 2018-03-19 17:54:44 -06:00
parent b14c9f8d68
commit f9e58c01ce
No known key found for this signature in database
GPG Key ID: 95684257D8F8B031
5 changed files with 42 additions and 36 deletions

View File

@ -82,7 +82,7 @@ fn expose_value_commitment<E, CS>(
CS: ConstraintSystem<E>
{
// Booleanize the value into little-endian bit order
let mut value_bits = boolean::u64_into_boolean_vec_le(
let value_bits = boolean::u64_into_boolean_vec_le(
cs.namespace(|| "value"),
value_commitment.as_ref().map(|c| c.value)
)?;
@ -121,9 +121,6 @@ fn expose_value_commitment<E, CS>(
// Expose the commitment as an input to the circuit
cv.inputize(cs.namespace(|| "commitment point"))?;
// Reorder value_bits so that it's big-endian
value_bits.reverse();
Ok(value_bits)
}
@ -624,7 +621,7 @@ fn test_input_circuit_with_bls12_381() {
assert!(cs.is_satisfied());
assert_eq!(cs.num_constraints(), 98776);
assert_eq!(cs.hash(), "2080d5f350cd7eff7742ab05dff18f82c0a2f29a5d2a758d805236067b2ed31f");
assert_eq!(cs.hash(), "ba8b2232a910b00399e90030c87c16a770e6e692fe3b4316675bdd7795df6e50");
assert_eq!(cs.num_inputs(), 8);
assert_eq!(cs.get_input(0, "ONE"), Fr::one());
@ -752,7 +749,7 @@ fn test_output_circuit_with_bls12_381() {
assert!(cs.is_satisfied());
assert_eq!(cs.num_constraints(), 7827);
assert_eq!(cs.hash(), "a7810a444f7ef6d0caa8ba026ce06e64654863cd0557241282ca337858039a53");
assert_eq!(cs.hash(), "8db50ff0e14fae19a7d83ef47f6da3a7e3e2644d251e37b387c6408d85df3ae7");
let expected_cm = payment_address.create_note(
value_commitment.value,

View File

@ -26,6 +26,8 @@ use std::io::{
Read
};
use util::swap_bits_u64;
// Represents the affine point (X/Z, Y/Z) via the extended
// twisted Edwards coordinates.
//
@ -89,34 +91,6 @@ impl<E: JubjubEngine, Subgroup> PartialEq for Point<E, Subgroup> {
}
}
fn swap_bits_u64(x: u64) -> u64
{
let mut tmp = 0;
for i in 0..64 {
tmp |= ((x >> i) & 1) << (63 - i);
}
tmp
}
#[test]
fn test_swap_bits_u64() {
assert_eq!(swap_bits_u64(17182120934178543809), 0b1000001100011011110000011000111000101111111001001100111001110111);
assert_eq!(swap_bits_u64(15135675916470734665), 0b1001001011110010001101010010001110110000100111010011000001001011);
assert_eq!(swap_bits_u64(6724233301461108393), 0b1001010101100000100011100001010111110001011000101000101010111010);
assert_eq!(swap_bits_u64(206708183275952289), 0b1000010100011010001010100011101011111111111110100111101101000000);
assert_eq!(swap_bits_u64(12712751566144824320), 0b0000000000100110010110111000001110001100001000110011011000001101);
let mut a = 15863238721320035327u64;
for _ in 0..1000 {
a = a.wrapping_mul(a);
let swapped = swap_bits_u64(a);
let unswapped = swap_bits_u64(swapped);
assert_eq!(a, unswapped);
}
}
impl<E: JubjubEngine> Point<E, Unknown> {
pub fn read<R: Read>(
reader: R,

View File

@ -15,3 +15,4 @@ pub mod circuit;
pub mod pedersen_hash;
pub mod primitives;
pub mod constants;
mod util;

View File

@ -28,6 +28,8 @@ use jubjub::{
use blake2_rfc::blake2s::Blake2s;
use util::swap_bits_u64;
#[derive(Clone)]
pub struct ValueCommitment<E: JubjubEngine> {
pub value: u64,
@ -193,8 +195,13 @@ impl<E: JubjubEngine> Note<E> {
// Calculate the note contents, as bytes
let mut note_contents = vec![];
// Write the value in big endian
(&mut note_contents).write_u64::<BigEndian>(self.value).unwrap();
// Write the value in little-endian bit order
// swapping the bits to ensure the order is
// correct (LittleEndian byte order would
// be incorrect here.)
(&mut note_contents).write_u64::<BigEndian>(
swap_bits_u64(self.value)
).unwrap();
// Write g_d
self.g_d.write(&mut note_contents).unwrap();

27
src/util.rs Normal file
View File

@ -0,0 +1,27 @@
pub fn swap_bits_u64(x: u64) -> u64
{
let mut tmp = 0;
for i in 0..64 {
tmp |= ((x >> i) & 1) << (63 - i);
}
tmp
}
#[test]
fn test_swap_bits_u64() {
assert_eq!(swap_bits_u64(17182120934178543809), 0b1000001100011011110000011000111000101111111001001100111001110111);
assert_eq!(swap_bits_u64(15135675916470734665), 0b1001001011110010001101010010001110110000100111010011000001001011);
assert_eq!(swap_bits_u64(6724233301461108393), 0b1001010101100000100011100001010111110001011000101000101010111010);
assert_eq!(swap_bits_u64(206708183275952289), 0b1000010100011010001010100011101011111111111110100111101101000000);
assert_eq!(swap_bits_u64(12712751566144824320), 0b0000000000100110010110111000001110001100001000110011011000001101);
let mut a = 15863238721320035327u64;
for _ in 0..1000 {
a = a.wrapping_mul(a);
let swapped = swap_bits_u64(a);
let unswapped = swap_bits_u64(swapped);
assert_eq!(a, unswapped);
}
}