Certs work, add integer modpow to MIMC52 for armel.

This commit is contained in:
Adam Ierymenko 2021-01-13 13:19:31 -05:00
parent ba9c51ead1
commit e2dbfc12a5
No known key found for this signature in database
GPG key ID: C8877CF2D7A5D7F3
4 changed files with 47 additions and 9 deletions

View file

@ -42,9 +42,31 @@ const uint32_t ZT_MIMC52_PRIMES[1024] = {4294895267, 4294895477, 4294895513, 429
4294963313, 4294963349, 4294963427, 4294963547, 4294963559, 4294963721, 4294963799, 4294963817, 4294963901, 4294963919, 4294964021, 4294964279, 4294964297, 4294964363, 4294964387, 4294964411, 4294964567, 4294964603, 4294964687, 4294964777, 4294965041, 4294965071, 4294965119, 4294965221, 4294965251, 4294965287, 4294965413, 4294965569, 4294965647, 4294965671, 4294965689, 4294965779, 4294965839, 4294965893, 4294966091, 4294966109, 4294966127, 4294966157, 4294966187, 4294966199, 4294966211, 4294966403, 4294966457, 4294966499, 4294966541, 4294966637,
4294966661, 4294966739, 4294966823, 4294966883, 4294966901, 4294966961, 4294967027, 4294967087, 4294967099, 4294967123, 4294967153, 4294967249};
// 52-bit mulmod using FPU hack to achieve better performance than the majority of CPU dividers.
#ifdef ZT_NO_IEEE_DOUBLE
// Integer 64-bit modular multiply for systems without an IEEE FPU. This is
// much slower on systems that can use the FPU hack.
static uint64_t mulmod64(uint64_t a, uint64_t b, const uint64_t m)
{
uint64_t res = 0;
while ((a)) {
if ((a << 63U))
res = (res + b) % m;
a >>= 1U;
b = (b << 1U) % m;
}
return res;
}
#define mulmod52(a, b, m, mf) mulmod64((a), (b), (m))
#else
// 52-bit mulmod using FPU hack, which is very fast on most systems with IEEE 64-bit floats.
#define mulmod52(a, b, m, mf) ( ( ( a * b ) - ( ((uint64_t)(((double)a * (double)b) / mf) - 1) * m ) ) % m )
#endif
// Compute a^e%m (mf is m in floating point form to avoid repeated conversion)
ZT_INLINE uint64_t modpow52(uint64_t a, uint64_t e, const uint64_t m, const double mf)
{

View file

@ -16,6 +16,24 @@
#include "Constants.hpp"
/*
* This is a verifiable delay function (or serial proof of work) based on
* the MIMC prime field hash construction. MIMC is very fast to execute in
* one direction and inherently a lot slower in another, allowing expensive
* work to be quickly verified. The 52-bit algorithm implemented here can
* run very fast on a variety of systems by taking advantage of the
* interesting double precision FPU modular multiplication hack described
* here:
*
* https://stackoverflow.com/a/50479693
*
* 52 bits is not sufficient for high strength cryptographic applications
* like block chains, but is good enough to add a deterministic delay to
* identity generation. That's its only purpose here. This is used as the
* delay function for "type 1" identities to replace the ad-hoc memory hard
* hash used in "type 0." This is both simpler and faster to verify.
*/
namespace ZeroTier {
namespace MIMC52 {

View file

@ -663,7 +663,7 @@ impl Certificate {
timestamp: c.timestamp,
validity: c.validity,
subject: CertificateSubject::new_from_capi(&c.subject),
issuer: if c.issuer.is_null() { None } else { Some(Identity::new_from_capi(c.issuer, false)) },
issuer: if c.issuer.is_null() { None } else { Some(Identity::new_from_capi(c.issuer, false).clone()) },
issuer_name: CertificateName::new_from_capi(&c.issuerName),
extended_attributes: Vec::from(std::slice::from_raw_parts(c.extendedAttributes, c.extendedAttributesSize as usize)),
max_path_length: c.maxPathLength as u32,
@ -855,9 +855,6 @@ mod tests {
let cert_signed_decoded = cert_signed_decoded.ok().unwrap();
assert!(cert_signed_decoded.signature.len() > 0);
let cert_signed_verified = cert_signed_decoded.verify();
println!("{}", cert_signed_decoded.to_json().as_str());
println!("{}", cert_signed_verified.to_string());
assert!(cert_signed_verified == CertificateError::None);
assert!(cert_signed_decoded.verify() == CertificateError::None);
}
}

View file

@ -20,7 +20,7 @@ use num_traits::{FromPrimitive, ToPrimitive};
use crate::*;
use crate::bindings::capi as ztcore;
#[derive(FromPrimitive,ToPrimitive)]
#[derive(FromPrimitive, ToPrimitive, PartialEq, Eq)]
pub enum IdentityType {
Curve25519 = ztcore::ZT_IdentityType_ZT_IDENTITY_TYPE_C25519 as isize,
NistP384 = ztcore::ZT_IdentityType_ZT_IDENTITY_TYPE_P384 as isize,
@ -78,10 +78,11 @@ impl Identity {
fn intl_to_string(&self, include_private: bool) -> String {
let mut buf: MaybeUninit<[c_char; 4096]> = MaybeUninit::uninit();
unsafe {
if ztcore::ZT_Identity_toString(self.capi, (*buf.as_mut_ptr()).as_mut_ptr(), 4096, if include_private { 1 } else { 0 }).is_null() {
let bufptr = (*buf.as_mut_ptr()).as_mut_ptr();
if ztcore::ZT_Identity_toString(self.capi, bufptr, 4096, if include_private { 1 } else { 0 }).is_null() {
return String::from("(invalid)");
}
return cstr_to_string((*buf.as_ptr()).as_ptr(), 4096);
return cstr_to_string(bufptr, 4096);
}
}