mirror of
https://github.com/logos-co/nomos-specs.git
synced 2025-02-13 07:46:35 +00:00
switch to curve25519-dalek
This commit is contained in:
parent
8205f027db
commit
bf25df4c6e
@ -16,6 +16,6 @@ rand_core = "0.6.0"
|
||||
rand_chacha = "0.3.1"
|
||||
lazy_static = "1.4.0"
|
||||
hex = "0.4.3"
|
||||
k256 = {version = "0.13.3", features = ["serde", "hash2curve"]}
|
||||
|
||||
curve25519-dalek = {version = "4.1", features = ["serde", "digest", "rand_core"]}
|
||||
sha2 = "0.10"
|
||||
|
||||
|
@ -1,33 +1,25 @@
|
||||
use curve25519_dalek::{ristretto::RistrettoPoint, traits::VartimeMultiscalarMul, Scalar};
|
||||
use lazy_static::lazy_static;
|
||||
use rand_core::RngCore;
|
||||
use rand_core::CryptoRngCore;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use k256::{
|
||||
elliptic_curve::{
|
||||
group::GroupEncoding, Field
|
||||
},
|
||||
ProjectivePoint, Scalar, AffinePoint
|
||||
};
|
||||
use k256::elliptic_curve::ops::LinearCombinationExt;
|
||||
|
||||
|
||||
lazy_static! {
|
||||
// Precompute of `crate::crypto::hash_to_curve(b"NOMOS_CL_PEDERSON_COMMITMENT_BLINDING")`
|
||||
static ref PEDERSON_COMMITMENT_BLINDING_POINT: ProjectivePoint = ProjectivePoint::from_bytes((&[3, 130, 21, 159, 218, 6, 221, 181, 55, 169, 198, 220, 102, 48, 164, 23, 206, 225, 58, 54, 247, 64, 180, 120, 247, 101, 88, 97, 2, 206, 144, 92, 9]).into()).unwrap();
|
||||
// Precompute of ``
|
||||
static ref PEDERSON_COMMITMENT_BLINDING_POINT: RistrettoPoint = crate::crypto::hash_to_curve(b"NOMOS_CL_PEDERSON_COMMITMENT_BLINDING");
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize)]
|
||||
pub struct Balance(pub AffinePoint);
|
||||
pub struct Balance(pub RistrettoPoint);
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize)]
|
||||
pub struct BalanceWitness {
|
||||
pub value: u64,
|
||||
pub unit: AffinePoint,
|
||||
pub unit: RistrettoPoint,
|
||||
pub blinding: Scalar,
|
||||
}
|
||||
|
||||
impl Balance {
|
||||
pub fn to_bytes(&self) -> [u8; 33] {
|
||||
self.0.to_bytes().into()
|
||||
pub fn to_bytes(&self) -> [u8; 32] {
|
||||
self.0.compress().to_bytes().into()
|
||||
}
|
||||
}
|
||||
|
||||
@ -40,8 +32,8 @@ impl BalanceWitness {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn random(value: u64, unit: impl Into<String>, rng: impl RngCore) -> Self {
|
||||
Self::new(value, unit, Scalar::random(rng))
|
||||
pub fn random(value: u64, unit: impl Into<String>, mut rng: impl CryptoRngCore) -> Self {
|
||||
Self::new(value, unit, Scalar::random(&mut rng))
|
||||
}
|
||||
|
||||
pub fn commit(&self) -> Balance {
|
||||
@ -49,13 +41,17 @@ impl BalanceWitness {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn unit_point(unit: &str) -> ProjectivePoint {
|
||||
pub fn unit_point(unit: &str) -> RistrettoPoint {
|
||||
crate::crypto::hash_to_curve(unit.as_bytes())
|
||||
}
|
||||
|
||||
pub fn balance(value: u64, unit: ProjectivePoint, blinding: Scalar) -> ProjectivePoint {
|
||||
pub fn balance(value: u64, unit: RistrettoPoint, blinding: Scalar) -> RistrettoPoint {
|
||||
let value_scalar = Scalar::from(value);
|
||||
ProjectivePoint::lincomb_ext(&[(unit, value_scalar), (*PEDERSON_COMMITMENT_BLINDING_POINT, blinding)])
|
||||
// can vartime leak the number of cycles through the stark proof?
|
||||
RistrettoPoint::vartime_multiscalar_mul(
|
||||
&[value_scalar, blinding],
|
||||
&[unit, *PEDERSON_COMMITMENT_BLINDING_POINT],
|
||||
)
|
||||
}
|
||||
|
||||
// mod serde_scalar {
|
||||
@ -152,16 +148,19 @@ pub fn balance(value: u64, unit: ProjectivePoint, blinding: Scalar) -> Projectiv
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
|
||||
use super::*;
|
||||
use crate::test_util::seed_rng;
|
||||
use k256::elliptic_curve::group::prime::PrimeCurveAffine;
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_pederson_blinding_point_pre_compute() {
|
||||
// use k256::elliptic_curve::group::GroupEncoding;
|
||||
// println!("{:?}", <[u8;33]>::from((*PEDERSON_COMMITMENT_BLINDING_POINT).to_bytes()));
|
||||
|
||||
assert_eq!(*PEDERSON_COMMITMENT_BLINDING_POINT, crate::crypto::hash_to_curve(b"NOMOS_CL_PEDERSON_COMMITMENT_BLINDING"));
|
||||
assert_eq!(
|
||||
*PEDERSON_COMMITMENT_BLINDING_POINT,
|
||||
crate::crypto::hash_to_curve(b"NOMOS_CL_PEDERSON_COMMITMENT_BLINDING")
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -185,7 +184,10 @@ mod test {
|
||||
let a = a_w.commit();
|
||||
let b = b_w.commit();
|
||||
assert_ne!(a, b);
|
||||
assert_eq!(a.0.to_curve() - b.0.to_curve(), BalanceWitness::new(0, "NMO", r1 - r2).commit().0.to_curve());
|
||||
assert_eq!(
|
||||
a.0.to_curve() - b.0.to_curve(),
|
||||
BalanceWitness::new(0, "NMO", r1 - r2).commit().0.to_curve()
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -207,7 +209,10 @@ mod test {
|
||||
let two = BalanceWitness::new(2, "NMO", 0u32.into());
|
||||
|
||||
// Values of same unit are homomorphic
|
||||
assert_eq!(ten.commit().0.to_curve() - eight.commit().0.to_curve(), two.commit().0.to_curve());
|
||||
assert_eq!(
|
||||
ten.commit().0.to_curve() - eight.commit().0.to_curve(),
|
||||
two.commit().0.to_curve()
|
||||
);
|
||||
|
||||
// Blinding factors are also homomorphic.
|
||||
assert_eq!(
|
||||
|
@ -2,7 +2,7 @@ use std::collections::BTreeSet;
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use k256::{Scalar, ProjectivePoint};
|
||||
use curve25519_dalek::{constants::RISTRETTO_BASEPOINT_POINT, ristretto::RistrettoPoint, Scalar};
|
||||
|
||||
use crate::{
|
||||
error::Error,
|
||||
@ -31,12 +31,13 @@ pub struct BundleProof {
|
||||
}
|
||||
|
||||
impl Bundle {
|
||||
pub fn balance(&self) -> ProjectivePoint {
|
||||
pub fn balance(&self) -> RistrettoPoint {
|
||||
self.partials.iter().map(|ptx| ptx.balance()).sum()
|
||||
}
|
||||
|
||||
pub fn is_balanced(&self, balance_blinding_witness: Scalar) -> bool {
|
||||
self.balance() == crate::balance::balance(0, ProjectivePoint::GENERATOR, balance_blinding_witness)
|
||||
self.balance()
|
||||
== crate::balance::balance(0, RISTRETTO_BASEPOINT_POINT, balance_blinding_witness)
|
||||
}
|
||||
|
||||
pub fn prove(
|
||||
@ -65,7 +66,9 @@ impl Bundle {
|
||||
return Err(Error::ProofFailed);
|
||||
}
|
||||
|
||||
if self.balance() != crate::balance::balance(0, ProjectivePoint::GENERATOR, w.balance_blinding) {
|
||||
if self.balance()
|
||||
!= crate::balance::balance(0, RISTRETTO_BASEPOINT_POINT, w.balance_blinding)
|
||||
{
|
||||
return Err(Error::ProofFailed);
|
||||
}
|
||||
|
||||
@ -89,9 +92,8 @@ impl Bundle {
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use crate::{
|
||||
input::InputWitness, note::NoteWitness, nullifier::NullifierSecret, output::OutputWitness,
|
||||
partial_tx::PartialTxWitness, test_util::seed_rng,
|
||||
crypto::hash_to_curve,
|
||||
crypto::hash_to_curve, input::InputWitness, note::NoteWitness, nullifier::NullifierSecret,
|
||||
output::OutputWitness, partial_tx::PartialTxWitness, test_util::seed_rng,
|
||||
};
|
||||
|
||||
use super::*;
|
||||
@ -128,9 +130,19 @@ mod test {
|
||||
assert!(!bundle.is_balanced(bundle_witness.balance_blinding));
|
||||
assert_eq!(
|
||||
bundle.balance(),
|
||||
crate::balance::balance(4840, hash_to_curve(b"CRV"), crv_4840_out.note.balance.blinding)
|
||||
- (crate::balance::balance(10, hash_to_curve(b"NMO"), nmo_10_in.note.balance.blinding)
|
||||
+ crate::balance::balance(23, hash_to_curve(b"ETH"), eth_23_in.note.balance.blinding))
|
||||
crate::balance::balance(
|
||||
4840,
|
||||
hash_to_curve(b"CRV"),
|
||||
crv_4840_out.note.balance.blinding
|
||||
) - (crate::balance::balance(
|
||||
10,
|
||||
hash_to_curve(b"NMO"),
|
||||
nmo_10_in.note.balance.blinding
|
||||
) + crate::balance::balance(
|
||||
23,
|
||||
hash_to_curve(b"ETH"),
|
||||
eth_23_in.note.balance.blinding
|
||||
))
|
||||
);
|
||||
|
||||
let crv_4840_in =
|
||||
@ -163,7 +175,7 @@ mod test {
|
||||
|
||||
assert_eq!(
|
||||
bundle.balance(),
|
||||
crate::balance::balance(0, ProjectivePoint::GENERATOR, witness.balance_blinding)
|
||||
crate::balance::balance(0, RistrettoPoint::GENERATOR, witness.balance_blinding)
|
||||
);
|
||||
|
||||
assert!(bundle.is_balanced(witness.balance_blinding));
|
||||
|
@ -1,8 +1,6 @@
|
||||
use k256::{Secp256k1, ProjectivePoint, elliptic_curve::{
|
||||
hash2curve::{GroupDigest, ExpandMsgXmd},
|
||||
},sha2::Sha256
|
||||
};
|
||||
use blake2::Blake2b512;
|
||||
use curve25519_dalek::ristretto::RistrettoPoint;
|
||||
|
||||
pub fn hash_to_curve(bytes: &[u8]) -> ProjectivePoint {
|
||||
Secp256k1::hash_from_bytes::<ExpandMsgXmd<Sha256>>(&[bytes], &[b"NOMOS_HASH_TO_CURVE"]).unwrap()
|
||||
pub fn hash_to_curve(bytes: &[u8]) -> RistrettoPoint {
|
||||
RistrettoPoint::hash_from_bytes::<Blake2b512>(bytes)
|
||||
}
|
||||
|
@ -105,11 +105,11 @@ impl Input {
|
||||
&& death_constraint_is_satisfied
|
||||
}
|
||||
|
||||
pub fn to_bytes(&self) -> [u8; 97] {
|
||||
let mut bytes = [0u8; 97];
|
||||
pub fn to_bytes(&self) -> [u8; 96] {
|
||||
let mut bytes = [0u8; 96];
|
||||
bytes[..32].copy_from_slice(self.note_comm.as_bytes());
|
||||
bytes[32..64].copy_from_slice(self.nullifier.as_bytes());
|
||||
bytes[64..97].copy_from_slice(&self.balance.to_bytes());
|
||||
bytes[64..96].copy_from_slice(&self.balance.to_bytes());
|
||||
bytes
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
use blake2::{Blake2s256, Digest};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use sha2::{Digest, Sha256};
|
||||
|
||||
pub fn padded_leaves<const N: usize>(elements: &[Vec<u8>]) -> [[u8; 32]; N] {
|
||||
let mut leaves = [[0u8; 32]; N];
|
||||
@ -13,14 +13,14 @@ pub fn padded_leaves<const N: usize>(elements: &[Vec<u8>]) -> [[u8; 32]; N] {
|
||||
}
|
||||
|
||||
pub fn leaf(data: &[u8]) -> [u8; 32] {
|
||||
let mut hasher = Blake2s256::new();
|
||||
let mut hasher = Sha256::new();
|
||||
hasher.update(b"NOMOS_MERKLE_LEAF");
|
||||
hasher.update(data);
|
||||
hasher.finalize().into()
|
||||
}
|
||||
|
||||
pub fn node(a: [u8; 32], b: [u8; 32]) -> [u8; 32] {
|
||||
let mut hasher = Blake2s256::new();
|
||||
let mut hasher = Sha256::new();
|
||||
hasher.update(b"NOMOS_MERKLE_NODE");
|
||||
hasher.update(a);
|
||||
hasher.update(b);
|
||||
|
@ -1,7 +1,6 @@
|
||||
use blake2::{Blake2s256, Digest};
|
||||
use rand_core::RngCore;
|
||||
use rand_core::CryptoRngCore;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use k256::elliptic_curve::group::GroupEncoding;
|
||||
|
||||
use crate::{
|
||||
balance::{Balance, BalanceWitness},
|
||||
@ -27,7 +26,12 @@ pub struct NoteWitness {
|
||||
}
|
||||
|
||||
impl NoteWitness {
|
||||
pub fn new(value: u64, unit: impl Into<String>, state: [u8; 32], rng: impl RngCore) -> Self {
|
||||
pub fn new(
|
||||
value: u64,
|
||||
unit: impl Into<String>,
|
||||
state: [u8; 32],
|
||||
rng: impl CryptoRngCore,
|
||||
) -> Self {
|
||||
Self {
|
||||
balance: BalanceWitness::random(value, unit, rng),
|
||||
death_constraint: vec![],
|
||||
@ -41,7 +45,7 @@ impl NoteWitness {
|
||||
|
||||
// COMMIT TO BALANCE
|
||||
hasher.update(self.balance.value.to_le_bytes());
|
||||
hasher.update(self.balance.unit.to_bytes());
|
||||
hasher.update(self.balance.unit.compress().to_bytes());
|
||||
// Important! we don't commit to the balance blinding factor as that may make the notes linkable.
|
||||
|
||||
// COMMIT TO STATE
|
||||
|
@ -61,10 +61,10 @@ impl Output {
|
||||
&& self.balance == witness.note.balance()
|
||||
}
|
||||
|
||||
pub fn to_bytes(&self) -> [u8; 65] {
|
||||
let mut bytes = [0u8; 65];
|
||||
pub fn to_bytes(&self) -> [u8; 64] {
|
||||
let mut bytes = [0u8; 64];
|
||||
bytes[..32].copy_from_slice(self.note_comm.as_bytes());
|
||||
bytes[32..65].copy_from_slice(&self.balance.to_bytes());
|
||||
bytes[32..64].copy_from_slice(&self.balance.to_bytes());
|
||||
bytes
|
||||
}
|
||||
}
|
||||
|
@ -2,9 +2,8 @@ use std::collections::BTreeSet;
|
||||
|
||||
use rand_core::RngCore;
|
||||
// use risc0_groth16::ProofJson;
|
||||
use curve25519_dalek::ristretto::RistrettoPoint;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use k256::ProjectivePoint;
|
||||
use k256::elliptic_curve::group::prime::PrimeCurveAffine;
|
||||
|
||||
use crate::error::Error;
|
||||
use crate::input::{Input, InputProof, InputWitness};
|
||||
@ -158,9 +157,9 @@ impl PartialTx {
|
||||
.all(|(o, p)| o.verify(p))
|
||||
}
|
||||
|
||||
pub fn balance(&self) -> ProjectivePoint {
|
||||
let in_sum: ProjectivePoint = self.inputs.iter().map(|i| i.balance.0.to_curve()).sum();
|
||||
let out_sum: ProjectivePoint = self.outputs.iter().map(|o| o.balance.0.to_curve()).sum();
|
||||
pub fn balance(&self) -> RistrettoPoint {
|
||||
let in_sum: RistrettoPoint = self.inputs.iter().map(|i| i.balance.0).sum();
|
||||
let out_sum: RistrettoPoint = self.outputs.iter().map(|o| o.balance.0).sum();
|
||||
|
||||
out_sum - in_sum
|
||||
}
|
||||
@ -169,7 +168,9 @@ impl PartialTx {
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
|
||||
use crate::{note::NoteWitness, nullifier::NullifierSecret, test_util::seed_rng, crypto::hash_to_curve};
|
||||
use crate::{
|
||||
crypto::hash_to_curve, note::NoteWitness, nullifier::NullifierSecret, test_util::seed_rng,
|
||||
};
|
||||
|
||||
use super::*;
|
||||
|
||||
@ -223,8 +224,15 @@ mod test {
|
||||
assert_eq!(
|
||||
ptx.balance(),
|
||||
crate::balance::balance(4840, hash_to_curve(b"CRV"), crv_4840.note.balance.blinding)
|
||||
- (crate::balance::balance(10, hash_to_curve(b"NMO"), nmo_10.note.balance.blinding)
|
||||
+ crate::balance::balance(23, hash_to_curve(b"ETH"), eth_23.note.balance.blinding))
|
||||
- (crate::balance::balance(
|
||||
10,
|
||||
hash_to_curve(b"NMO"),
|
||||
nmo_10.note.balance.blinding
|
||||
) + crate::balance::balance(
|
||||
23,
|
||||
hash_to_curve(b"ETH"),
|
||||
eth_23.note.balance.blinding
|
||||
))
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -13,6 +13,6 @@ lto = true
|
||||
[patch.crates-io]
|
||||
# Placing these patch statement in the workspace Cargo.toml will add RISC Zero SHA-256 and bigint
|
||||
# multiplication accelerator support for all downstream usages of the following crates.
|
||||
sha2 = { git = "https://github.com/risc0/RustCrypto-hashes", tag = "sha2-v0.10.8-risczero.0" }
|
||||
k256 = { git = "https://github.com/risc0/RustCrypto-elliptic-curves", tag = "k256/v0.13.3-risczero.0" }
|
||||
crypto-bigint = { git = "https://github.com/risc0/RustCrypto-crypto-bigint", tag = "v0.5.2-risczero.0" }
|
||||
#sha2 = { git = "https://github.com/risc0/RustCrypto-hashes", tag = "sha2-v0.10.8-risczero.0" }
|
||||
#k256 = { git = "https://github.com/risc0/RustCrypto-elliptic-curves", tag = "k256/v0.13.3-risczero.0" }
|
||||
#crypto-bigint = { git = "https://github.com/risc0/RustCrypto-crypto-bigint", tag = "v0.5.5-risczero.0" }
|
||||
|
@ -21,4 +21,5 @@ cl = { path = "../../../cl" }
|
||||
# multiplication accelerator support for all downstream usages of the following crates.
|
||||
sha2 = { git = "https://github.com/risc0/RustCrypto-hashes", tag = "sha2-v0.10.8-risczero.0" }
|
||||
k256 = { git = "https://github.com/risc0/RustCrypto-elliptic-curves", tag = "k256/v0.13.3-risczero.0" }
|
||||
crypto-bigint = { git = "https://github.com/risc0/RustCrypto-crypto-bigint", tag = "v0.5.2-risczero.0" }
|
||||
crypto-bigint = { git = "https://github.com/risc0/RustCrypto-crypto-bigint", tag = "v0.5.5-risczero.0" }
|
||||
curve25519-dalek = { git = "https://github.com/risc0/curve25519-dalek", tag = "curve25519-4.1.2-risczero.0" }
|
||||
|
Loading…
x
Reference in New Issue
Block a user