Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RSA Accumulators / Vector Commitments #9

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 10 additions & 10 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,16 +19,16 @@ use rkyv::{Archive, Deserialize, Serialize};

// Internal imports
// pub mod p2p;
pub mod rsa;
pub mod vc;
pub mod vdf;

use crate::PoL::*;
use sm::sm;
use vdf::evaluation::{DeserializableVDFResult, VDF};
use vdf::proof::{DeserializableVDFProof, VDFProof};
use vdf::InvalidCapError;

// RSA-2048, copied from Wikipedia
pub const RSA_2048: &str = "2519590847565789349402718324004839857142928212620403202777713783604366202070759555626401852588078440691829064124951508218929855914917618450280848912007284499268739280728777673597141834727026189637501497182469116507761337985909570009733045974880842840179742910064245869181719511874612151517265463228221686998754918242243363725908514186546204357679842338718477444792073993423658482382428119816381501067481045166037730605620161967625613384414360383390441495263443219011465754445417842402092461651572335077870774981712577246796292638635637328991215483143816789988504044536402352738195137863656439121201039712282120720357";

// State machine macro for handling the protocol state
sm!(
PoL {
Expand Down Expand Up @@ -528,13 +528,13 @@ impl ProofOfLatency {
#[cfg(test)]
mod tests {
use super::*;
use crate::rsa::RSA_2048;
use ramp_primes::Verification;
use std::str::FromStr;

#[test]
fn runs_without_blocking() {
let modulus = Int::from_str(RSA_2048).unwrap();
let mut pol = ProofOfLatency::default().init(modulus, u32::MAX);
let modulus = &*RSA_2048;
let mut pol = ProofOfLatency::default().init(modulus.clone(), u32::MAX);

let (_input, _output) = pol.open_io();

Expand All @@ -543,19 +543,19 @@ mod tests {

#[test]
fn generator_combiner_is_commutative() {
let modulus = Int::from_str(RSA_2048).unwrap();
let modulus = &*RSA_2048;
let rand1 = Generator::new_uint(128);
let rand2 = Generator::new_uint(128);
let pol = ProofOfLatency::default().init(modulus, u32::MAX);
let pol = ProofOfLatency::default().init(modulus.clone(), u32::MAX);
let result1 = pol.combine_generator_parts(&rand1, &rand2);
let result2 = pol.combine_generator_parts(&rand2, &rand1);
assert_eq!(result1, result2);
}

#[test]
fn runs_prover_state_machine_in_correct_order() {
let modulus = Int::from_str(RSA_2048).unwrap();
let mut pol = ProofOfLatency::default().init(modulus, 42);
let modulus = &*RSA_2048;
let mut pol = ProofOfLatency::default().init(modulus.clone(), 42);
let (input, output) = pol.open_io();

assert!(pol.start(PoLRole::Prover).is_ok());
Expand Down
15 changes: 7 additions & 8 deletions src/main.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
#[macro_use]
extern crate log;

use proof_of_latency::rsa::RSA_2048;
use proof_of_latency::vdf::util::hash_to_prime;
use proof_of_latency::{PoLMessage, PoLRole, ProofOfLatency, RSA_2048};
use ramp::Int;
use proof_of_latency::{PoLMessage, PoLRole, ProofOfLatency};

use ramp_primes::Generator;
use std::time::Instant;
// use ockam::{Context, Result, Route, SecureChannel, TcpTransport, Vault, TCP};
Expand Down Expand Up @@ -41,21 +42,19 @@ fn main() {
// // Wait to receive a reply and print it.
// let reply = ctx.receive::<String>().await?;
// println!("App Received: {}", reply); // should print "Hello Ockam!"

let modulus = Int::from_str_radix(RSA_2048, 10).unwrap();

let modulus = &*RSA_2048;
let timer = Instant::now();
let prime1 = hash_to_prime("asdfhjaefhliuefeajie", &modulus);
let prime1 = hash_to_prime("asdfhjaefhliuefeajie", modulus);
debug!(
"Prime {:?} calculated in {:?}ms",
prime1,
timer.elapsed().as_millis()
);

let diff = &prime1 - &modulus;
let diff = &prime1 - modulus;
debug!("The prime is {:?} larger than the modulus!", diff);

let mut pol = ProofOfLatency::default().init(modulus, 150000);
let mut pol = ProofOfLatency::default().init(modulus.clone(), 150000);
let (input, output) = pol.open_io();
debug!("Proof of latency instance created");

Expand Down
132 changes: 132 additions & 0 deletions src/rsa/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
use lazy_static::lazy_static;
use ramp::Int;
use std::cmp::Ordering;
use std::error::Error;
use std::fmt;
use std::ops::{Add, Div, Mul, Sub};

pub const RSA_2048_STR: &str = "2519590847565789349402718324004839857142928212620403202777713783604366202070759555626401852588078440691829064124951508218929855914917618450280848912007284499268739280728777673597141834727026189637501497182469116507761337985909570009733045974880842840179742910064245869181719511874612151517265463228221686998754918242243363725908514186546204357679842338718477444792073993423658482382428119816381501067481045166037730605620161967625613384414360383390441495263443219011465754445417842402092461651572335077870774981712577246796292638635637328991215483143816789988504044536402352738195137863656439121201039712282120720357";

lazy_static! {
pub static ref TWO: Int = Int::from_str_radix("2", 10).unwrap();
pub static ref RSA_2048: Int =
Int::from_str_radix(RSA_2048_STR, 10).unwrap();
}

#[derive(Debug)]
pub struct UnmatchingModulusError;

impl fmt::Display for UnmatchingModulusError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "Mismatch between the RSA modulo!")
}
}

impl Error for UnmatchingModulusError {
fn description(&self) -> &str {
"Mismatch between the RSA modulo!"
}
}

#[derive(Debug, Clone, Eq)]
pub struct RSA(Int, Int);

impl Add for RSA {
type Output = Self;
fn add(self, other: Self) -> Self {
Self(self.0 + other.0, self.1)
}
}

impl Sub for RSA {
type Output = Self;
fn sub(self, other: Self) -> Self {
Self(self.0 - other.0, self.1)
}
}

impl Mul for RSA {
type Output = Self;
fn mul(self, other: Self) -> Self {
Self(self.0 * other.0, self.1)
}
}

impl Div for RSA {
type Output = Self;
fn div(self, other: Self) -> Self {
Self(self.0 / other.0, self.1)
}
}

impl Ord for RSA {
fn cmp(&self, other: &Self) -> Ordering {
self.0.cmp(&other.0)
}
}

impl PartialOrd for RSA {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(self.cmp(other))
}
}

impl PartialEq for RSA {
fn eq(&self, other: &Self) -> bool {
self.0 == other.0
}
}

impl Default for RSA {
fn default() -> Self {
RSA(TWO.clone(), RSA_2048.clone())
}
}

impl RSA {
pub fn new(generator: Int, modulus: Int) -> Self {
Self(generator, modulus)
}
pub fn next_square(&self) -> Self {
let next = self.0.pow_mod(&TWO, &self.1);
Self(next, self.1.clone())
}
pub fn pow(&self, power: &Int) -> Self {
let next = self.0.pow_mod(power, &self.1);
Self(next, self.1.clone())
}
pub fn as_int(&self) -> Int {
self.0.clone()
}
pub fn get_modulus(&self) -> Int {
self.1.clone()
}
pub fn deserialize(&self) -> String {
self.0.to_str_radix(10, false)
}
}

#[cfg(test)]
mod tests {
use super::*;
use ramp::Int;

#[test]
fn rsa_squaring() {
let generator =
Int::from_str_radix("78905317890531857319", 10).unwrap();
let rsa = RSA(generator, RSA_2048.clone());
let next = rsa.next_square();
assert!(rsa != next);
}

#[test]
fn rsa_pow() {
let generator =
Int::from_str_radix("97556298743265743962543", 10).unwrap();
let rsa = RSA(generator, RSA_2048.clone());
let power = Int::from_str_radix("77698319831", 10).unwrap();
let next = rsa.pow(&power);
assert!(rsa != next);
}
}
1 change: 1 addition & 0 deletions src/vc/acc.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@

2 changes: 2 additions & 0 deletions src/vc/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
pub mod acc;
pub mod poe;
78 changes: 78 additions & 0 deletions src/vc/poe.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
use crate::rsa::{UnmatchingModulusError, RSA};
use crate::vdf::util::hash_to_prime;
use ramp::Int;

#[derive(Debug, Clone)]
pub struct ProofOfExponentiation {
previous: RSA,
exponent: Int,
current: RSA,
proof: RSA,
}

impl ProofOfExponentiation {
pub fn new(previous: RSA, exponent: Int, current: RSA) -> Self {
let unique_prime = hash_to_prime(
&(&previous.as_int() + &exponent + &current.as_int())
.to_str_radix(10, false),
&current.get_modulus(),
);
let witness = &exponent / &unique_prime;
let proof = previous.pow(&witness);
Self {
previous,
exponent,
current,
proof,
}
}
pub fn verify(self) -> bool {
let unique_prime = hash_to_prime(
&(&self.previous.as_int()
+ &self.exponent
+ &self.current.as_int())
.to_str_radix(10, false),
&self.current.get_modulus(),
);
let r = &self.exponent % &unique_prime;
let w = self.proof.pow(&unique_prime) * self.previous.pow(&r);
w == self.current
}
}

#[cfg(test)]
mod tests {
use super::*;
use crate::rsa::RSA;
use proptest::prelude::*;
use ramp::Int;

proptest! {
#[test]
fn poe_proptest(m in 0u16..u16::MAX, g in 0u16..u16::MAX, e in 0u16..u16::MAX) {
let modulus = Int::from(m);
let generator =
&RSA::new(Int::from(g), modulus.clone());
let exponent = Int::from(e);
let current = RSA::new(generator.pow(&exponent).as_int(), modulus.clone());
let proof =
ProofOfExponentiation::new(generator.clone(), exponent, current);
assert!(proof.verify());
}
}

#[test]
fn poe_test() {
let modulus = &Int::from_str_radix("133769", 10).unwrap();
let generator = &RSA::new(
Int::from_str_radix("120420", 10).unwrap(),
modulus.clone(),
);
let exponent = Int::from_str_radix("47", 10).unwrap();
let current =
RSA::new(generator.pow(&exponent).as_int(), modulus.clone());
let proof =
ProofOfExponentiation::new(generator.clone(), exponent, current);
assert!(proof.verify());
}
}
20 changes: 11 additions & 9 deletions src/vdf/evaluation.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
use crate::rsa;
use crate::vdf;

use crossbeam::channel::unbounded;
use crossbeam::channel::{Receiver, Sender};
use ramp::Int;
Expand All @@ -12,7 +14,7 @@ use std::{thread, time};
/// The end result of the VDF which we still need to prove
#[derive(Debug, Clone, Default)]
pub struct VDFResult {
pub result: Int,
pub result: rsa::RSA,
pub iterations: u32,
}

Expand All @@ -26,7 +28,10 @@ pub struct DeserializableVDFResult {
impl DeserializableVDFResult {
pub fn serialize(&self) -> VDFResult {
VDFResult {
result: Int::from_str_radix(&self.result, 10).unwrap(),
result: rsa::RSA::new(
Int::from_str_radix(&self.result, 10).unwrap(),
rsa::RSA_2048.clone(),
),
iterations: self.iterations,
}
}
Expand Down Expand Up @@ -54,7 +59,7 @@ impl PartialEq for VDFResult {
impl VDFResult {
pub fn deserialize(&self) -> DeserializableVDFResult {
DeserializableVDFResult {
result: self.result.to_str_radix(10, false),
result: self.result.deserialize(),
iterations: self.iterations,
}
}
Expand All @@ -78,7 +83,6 @@ pub struct VDF {
pub upper_bound: u32,
pub cap: Int,
pub result: VDFResult,
two: Int,
pub proof_type: vdf::proof::ProofType,
proof_nudger: Option<Sender<bool>>,
proof_receiver: Option<Receiver<vdf::proof::VDFProof>>,
Expand All @@ -89,8 +93,7 @@ impl Iterator for VDF {
fn next(&mut self) -> Option<VDFResult> {
if self.result.iterations < self.upper_bound {
self.result.iterations += 1;
self.result.result =
self.result.result.pow_mod(&self.two, &self.modulus);
self.result.result = self.result.result.clone().next_square();
Some(self.result.clone())
} else {
None
Expand Down Expand Up @@ -137,15 +140,14 @@ impl VDF {
proof_type: vdf::proof::ProofType,
) -> Self {
Self {
modulus,
modulus: modulus.clone(),
generator: generator.clone(),
upper_bound,
cap: Int::zero(),
result: VDFResult {
result: generator,
result: rsa::RSA::new(generator, modulus),
iterations: 0,
},
two: Int::from(2),
proof_type,
proof_nudger: None,
proof_receiver: None,
Expand Down
Loading