bp_pp/range_proof/
u64_proof.rs1#![allow(non_snake_case)]
2use std::ops::{Add, Mul};
5use k256::{ProjectivePoint, Scalar};
6use k256::elliptic_curve::rand_core::{CryptoRng, RngCore};
7use merlin::Transcript;
8use crate::range_proof::reciprocal::{Proof, ReciprocalRangeProofProtocol, Witness};
9
10#[allow(dead_code)]
11const G_VEC_CIRCUIT_SZ: usize = 16;
12pub const G_VEC_FULL_SZ: usize = 16;
13pub const H_VEC_CIRCUIT_SZ: usize = 26;
14pub const H_VEC_FULL_SZ: usize = 32;
15
16
17#[derive(Clone, Debug)]
19pub struct U64RangeProofProtocol {
20 pub g: ProjectivePoint,
22 pub g_vec: Vec<ProjectivePoint>,
24
25 pub h_vec: Vec<ProjectivePoint>,
28}
29
30impl U64RangeProofProtocol {
31 pub const DIM_ND: usize = 16;
33 pub const DIM_NP: usize = 16;
35
36 pub fn commit_value(&self, x: u64, s: &Scalar) -> ProjectivePoint {
38 self.g.mul(&Scalar::from(x)).add(&self.h_vec[0].mul(s))
39 }
40
41 pub fn verify(&self, v: &ProjectivePoint, proof: Proof, t: &mut Transcript) -> bool {
43 let reciprocal = ReciprocalRangeProofProtocol {
44 dim_nd: Self::DIM_ND,
45 dim_np: Self::DIM_NP,
46 g: self.g,
47 g_vec: self.g_vec.clone(),
48 h_vec: self.h_vec[..H_VEC_CIRCUIT_SZ].to_vec(),
49 g_vec_: vec![],
50 h_vec_: self.h_vec[H_VEC_CIRCUIT_SZ..].to_vec(),
51 };
52
53 reciprocal.verify(v, proof, t)
54 }
55
56 pub fn prove<R>(&self, x: u64, s: &Scalar, t: &mut Transcript, rng: &mut R) -> Proof
58 where
59 R: RngCore + CryptoRng
60 {
61 let digits = Self::u64_to_hex(x);
62 let poles = Self::u64_to_hex_mapped(x);
63
64 let reciprocal = ReciprocalRangeProofProtocol {
65 dim_nd: Self::DIM_ND,
66 dim_np: Self::DIM_NP,
67 g: self.g,
68 g_vec: self.g_vec.clone(),
69 h_vec: self.h_vec[..H_VEC_CIRCUIT_SZ].to_vec(),
70 g_vec_: vec![],
71 h_vec_: self.h_vec[H_VEC_CIRCUIT_SZ..].to_vec(),
72 };
73
74 let witness = Witness {
75 x: Scalar::from(x),
76 s: *s,
77 m: poles,
78 digits,
79 };
80
81 reciprocal.prove(&reciprocal.commit_value(&witness.x, &witness.s), witness, t, rng)
82 }
83
84 pub fn u64_to_hex(mut x: u64) -> Vec<Scalar> {
85 (0..16).map(|_| {
86 let val = Scalar::from(x % 16);
87 x /= 16;
88 val
89 }).collect::<Vec<Scalar>>()
90 }
91
92 pub fn u64_to_hex_mapped(mut x: u64) -> Vec<Scalar> {
93 let mut result = vec![Scalar::ZERO; 16];
94
95 (0..16).for_each(|_| {
96 let digit = (x % 16) as usize;
97 result[digit] = result[digit].add(Scalar::ONE);
98 x /= 16;
99 });
100
101 result
102 }
103}