Added serialization and test vectors for U256 and Fp elements.
This commit is contained in:
parent
77df6c9ee5
commit
cb2ff5c1ad
|
@ -14,3 +14,10 @@ name = "fp"
|
|||
|
||||
[dependencies]
|
||||
rand = "0.3.14"
|
||||
rustc-serialize = "0.3"
|
||||
byteorder = "0.5"
|
||||
|
||||
[dev-dependencies.bincode]
|
||||
version = "0.6.0"
|
||||
default-features = false
|
||||
features = ["rustc-serialize"]
|
||||
|
|
38
src/arith.rs
38
src/arith.rs
|
@ -1,11 +1,49 @@
|
|||
use std::cmp::Ordering;
|
||||
use rand::Rng;
|
||||
|
||||
use rustc_serialize::{Encodable, Encoder, Decodable, Decoder};
|
||||
use byteorder::{ByteOrder, BigEndian};
|
||||
|
||||
/// 256-bit, stack allocated biginteger for use in prime field
|
||||
/// arithmetic.
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
||||
pub struct U256([u64; 4]);
|
||||
|
||||
impl Encodable for U256 {
|
||||
fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
|
||||
let mut buf = [0; 32];
|
||||
|
||||
BigEndian::write_u64(&mut buf[0..], self.0[3]);
|
||||
BigEndian::write_u64(&mut buf[8..], self.0[2]);
|
||||
BigEndian::write_u64(&mut buf[16..], self.0[1]);
|
||||
BigEndian::write_u64(&mut buf[24..], self.0[0]);
|
||||
|
||||
for i in 0..32 {
|
||||
try!(s.emit_u8(buf[i]));
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl Decodable for U256 {
|
||||
fn decode<S: Decoder>(s: &mut S) -> Result<U256, S::Error> {
|
||||
let mut buf = [0; 32];
|
||||
|
||||
for i in 0..32 {
|
||||
buf[i] = try!(s.read_u8());
|
||||
}
|
||||
|
||||
let mut n = [0; 4];
|
||||
n[3] = BigEndian::read_u64(&buf[0..]);
|
||||
n[2] = BigEndian::read_u64(&buf[8..]);
|
||||
n[1] = BigEndian::read_u64(&buf[16..]);
|
||||
n[0] = BigEndian::read_u64(&buf[24..]);
|
||||
|
||||
Ok(n.into())
|
||||
}
|
||||
}
|
||||
|
||||
impl Ord for U256 {
|
||||
#[inline]
|
||||
fn cmp(&self, other: &U256) -> Ordering {
|
||||
|
|
|
@ -4,6 +4,8 @@ use std::fmt;
|
|||
use std::marker::PhantomData;
|
||||
use super::FieldElement;
|
||||
|
||||
use rustc_serialize::{Encodable, Encoder, Decodable, Decoder};
|
||||
|
||||
use arith::U256;
|
||||
|
||||
pub trait FpParams {
|
||||
|
@ -44,6 +46,20 @@ pub fn const_fp<P: FpParams, I: Into<U256>>(i: I) -> Fp<P> {
|
|||
Fp(i.into(), PhantomData)
|
||||
}
|
||||
|
||||
impl<P: FpParams> Encodable for Fp<P> {
|
||||
fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
|
||||
let normalized = U256::from(*self);
|
||||
|
||||
normalized.encode(s)
|
||||
}
|
||||
}
|
||||
|
||||
impl<P: FpParams> Decodable for Fp<P> {
|
||||
fn decode<S: Decoder>(s: &mut S) -> Result<Fp<P>, S::Error> {
|
||||
Fp::new(try!(U256::decode(s))).ok_or_else(|| s.error("integer is not less than modulus"))
|
||||
}
|
||||
}
|
||||
|
||||
impl<P: FpParams> Fp<P> {
|
||||
pub fn from_str(s: &str) -> Option<Self> {
|
||||
let ints: Vec<_> = {
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
extern crate rand;
|
||||
extern crate rustc_serialize;
|
||||
extern crate byteorder;
|
||||
|
||||
mod arith;
|
||||
mod fields;
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,23 @@
|
|||
extern crate bincode;
|
||||
extern crate rustc_serialize;
|
||||
|
||||
use self::bincode::SizeLimit::Infinite;
|
||||
use self::bincode::rustc_serialize::{encode, decode};
|
||||
use self::rustc_serialize::{Encodable, Decodable};
|
||||
use self::rustc_serialize::hex::{FromHex, ToHex};
|
||||
|
||||
pub fn into_hex<S: Encodable>(obj: S) -> Option<String> {
|
||||
encode(&obj, Infinite).ok().map(|e| e.to_hex())
|
||||
}
|
||||
|
||||
pub fn from_hex<S: Decodable>(s: &str) -> Option<S> {
|
||||
let s = s.from_hex().unwrap();
|
||||
|
||||
decode(&s).ok()
|
||||
}
|
||||
|
||||
pub fn reserialize<S: Encodable + Decodable>(obj: S) -> S {
|
||||
let s = into_hex(obj).unwrap();
|
||||
|
||||
from_hex(&s).unwrap()
|
||||
}
|
Loading…
Reference in New Issue