mirror of
https://github.com/saymrwulf/curve25519-dalek-source.git
synced 2026-09-07 20:50:39 +00:00
Initial work on Serde support
This commit is contained in:
parent
95758e5a86
commit
7c32271346
4 changed files with 155 additions and 0 deletions
|
|
@ -18,6 +18,15 @@ exclude = [
|
||||||
[badges]
|
[badges]
|
||||||
travis-ci = { repository = "isislovecruft/curve25519-dalek", branch = "master"}
|
travis-ci = { repository = "isislovecruft/curve25519-dalek", branch = "master"}
|
||||||
|
|
||||||
|
[dependencies.serde]
|
||||||
|
version = "1.0"
|
||||||
|
|
||||||
|
[dependencies.serde_json]
|
||||||
|
version = "1.0"
|
||||||
|
|
||||||
|
[dependencies.serde_cbor]
|
||||||
|
version = "0.6"
|
||||||
|
|
||||||
[dependencies.arrayref]
|
[dependencies.arrayref]
|
||||||
version = "0.3.3"
|
version = "0.3.3"
|
||||||
|
|
||||||
|
|
|
||||||
76
src/curve.rs
76
src/curve.rs
|
|
@ -278,6 +278,59 @@ impl CompressedMontgomeryU {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
// Serde support
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
// Serializes to and from `ExtendedPoint` directly, doing compression
|
||||||
|
// and decompression internally. This means that users can create
|
||||||
|
// structs containing `ExtendedPoint`s and use Serde's derived
|
||||||
|
// serializers to serialize those structures.
|
||||||
|
|
||||||
|
use serde::{Serialize, Deserialize};
|
||||||
|
use serde::{Serializer, Deserializer};
|
||||||
|
use serde::de::Visitor;
|
||||||
|
use serde;
|
||||||
|
|
||||||
|
impl Serialize for ExtendedPoint {
|
||||||
|
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||||
|
where S: Serializer
|
||||||
|
{
|
||||||
|
serializer.serialize_bytes(self.compress_edwards().as_bytes())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'de> Deserialize<'de> for ExtendedPoint {
|
||||||
|
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||||
|
where D: Deserializer<'de>
|
||||||
|
{
|
||||||
|
struct ExtendedPointVisitor;
|
||||||
|
|
||||||
|
impl<'de> Visitor<'de> for ExtendedPointVisitor {
|
||||||
|
type Value = ExtendedPoint;
|
||||||
|
|
||||||
|
fn expecting(&self, formatter: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
|
||||||
|
formatter.write_str("a valid point in Edwards y + sign format")
|
||||||
|
}
|
||||||
|
|
||||||
|
fn visit_bytes<E>(self, v: &[u8]) -> Result<ExtendedPoint, E>
|
||||||
|
where E: serde::de::Error
|
||||||
|
{
|
||||||
|
println!("VISIT_BYTES");
|
||||||
|
if v.len() == 32 {
|
||||||
|
let arr32 = array_ref!(v,0,32); // &[u8;32] from &[u8]
|
||||||
|
CompressedEdwardsY(*arr32).decompress()
|
||||||
|
.ok_or(serde::de::Error::custom("decompression failed"))
|
||||||
|
} else {
|
||||||
|
Err(serde::de::Error::invalid_length(v.len(), &self))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
println!("DESERIALIZE");
|
||||||
|
deserializer.deserialize_bytes(ExtendedPointVisitor)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
// Internal point representations
|
// Internal point representations
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
|
|
@ -1576,6 +1629,29 @@ mod test {
|
||||||
assert_eq!(result.compress_edwards(), DOUBLE_SCALAR_MULT_RESULT);
|
assert_eq!(result.compress_edwards(), DOUBLE_SCALAR_MULT_RESULT);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
use serde_cbor;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn serde_cbor_basepoint_roundtrip() {
|
||||||
|
let output = serde_cbor::to_vec(&constants::ED25519_BASEPOINT).unwrap();
|
||||||
|
let parsed: ExtendedPoint = serde_cbor::from_slice(&output).unwrap();
|
||||||
|
assert_eq!(parsed.compress_edwards(), constants::BASE_CMPRSSD);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
use serde_json;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn serde_json_basepoint_roundtrip() {
|
||||||
|
let output = serde_json::to_string(&constants::ED25519_BASEPOINT).unwrap();
|
||||||
|
println!("{:?}", output);
|
||||||
|
println!("{:?}", constants::BASE_CMPRSSD);
|
||||||
|
let parsed: ExtendedPoint = serde_json::from_str(&output).unwrap();
|
||||||
|
println!("{:?}", parsed);
|
||||||
|
panic!();
|
||||||
|
}
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
|
|
|
||||||
65
src/decaf.rs
65
src/decaf.rs
|
|
@ -108,6 +108,61 @@ impl Identity for CompressedDecaf {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
// Serde support
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
// Serializes to and from `DecafPoint` directly, doing compression
|
||||||
|
// and decompression internally. This means that users can create
|
||||||
|
// structs containing `DecafPoint`s and use Serde's derived
|
||||||
|
// serializers to serialize those structures.
|
||||||
|
|
||||||
|
use serde::{Serialize, Deserialize};
|
||||||
|
use serde::{Serializer, Deserializer};
|
||||||
|
use serde::de::Visitor;
|
||||||
|
use serde;
|
||||||
|
|
||||||
|
impl Serialize for DecafPoint {
|
||||||
|
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||||
|
where S: Serializer
|
||||||
|
{
|
||||||
|
serializer.serialize_bytes(self.compress().as_bytes())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'de> Deserialize<'de> for DecafPoint {
|
||||||
|
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||||
|
where D: Deserializer<'de>
|
||||||
|
{
|
||||||
|
struct DecafPointVisitor;
|
||||||
|
|
||||||
|
impl<'de> Visitor<'de> for DecafPointVisitor {
|
||||||
|
type Value = DecafPoint;
|
||||||
|
|
||||||
|
fn expecting(&self, formatter: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
|
||||||
|
formatter.write_str("a valid point in Decaf format")
|
||||||
|
}
|
||||||
|
|
||||||
|
fn visit_bytes<E>(self, v: &[u8]) -> Result<DecafPoint, E>
|
||||||
|
where E: serde::de::Error
|
||||||
|
{
|
||||||
|
if v.len() == 32 {
|
||||||
|
let arr32 = array_ref!(v,0,32); // &[u8;32] from &[u8]
|
||||||
|
CompressedDecaf(*arr32).decompress()
|
||||||
|
.ok_or(serde::de::Error::custom("decompression failed"))
|
||||||
|
} else {
|
||||||
|
Err(serde::de::Error::invalid_length(v.len(), &self))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
deserializer.deserialize_bytes(DecafPointVisitor)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
// Internal point representations
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
|
||||||
/// A point in a prime-order group.
|
/// A point in a prime-order group.
|
||||||
///
|
///
|
||||||
/// XXX think about how this API should work
|
/// XXX think about how this API should work
|
||||||
|
|
@ -381,6 +436,16 @@ mod test {
|
||||||
use curve::Identity;
|
use curve::Identity;
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
|
use serde_cbor;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn serde_cbor_basepoint_roundtrip() {
|
||||||
|
let output = serde_cbor::to_vec(&constants::DECAF_ED25519_BASEPOINT).unwrap();
|
||||||
|
let parsed: DecafPoint = serde_cbor::from_slice(&output).unwrap();
|
||||||
|
assert_eq!(parsed, constants::DECAF_ED25519_BASEPOINT);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn decaf_decompress_negative_s_fails() {
|
fn decaf_decompress_negative_s_fails() {
|
||||||
// constants::d is neg, so decompression should fail as |d| != d.
|
// constants::d is neg, so decompression should fail as |d| != d.
|
||||||
|
|
|
||||||
|
|
@ -47,6 +47,11 @@ extern crate arrayref;
|
||||||
extern crate generic_array;
|
extern crate generic_array;
|
||||||
extern crate digest;
|
extern crate digest;
|
||||||
|
|
||||||
|
//#[cfg(feature = "serde")]
|
||||||
|
extern crate serde;
|
||||||
|
extern crate serde_cbor;
|
||||||
|
extern crate serde_json;
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
extern crate core;
|
extern crate core;
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue