Skip to content

Commit ba4c9ea

Browse files
authored
Merge pull request #9 from ZeroPass/develop
Add SHA-384, EC point in Jacobi coords and optimize `ec_mul_add_fast`
2 parents 2cb3d21 + 62a6111 commit ba4c9ea

35 files changed

+9860
-1662
lines changed

.gitignore

+6
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@
33
##
44
## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
55

6+
# tv generated code
7+
tests/tv/**/*.hpp
8+
69
# User-specific files
710
*.rsuser
811
*.suo
@@ -355,3 +358,6 @@ MigrationBackup/
355358

356359
# Built Visual Studio Code Extensions
357360
*.vsix
361+
362+
# Allow RSP test vectors
363+
!tests/tv/**/*.rsp

README.md

+30-5
Original file line numberDiff line numberDiff line change
@@ -82,16 +82,38 @@ If configured correctly, you should be able to add the antelope.ck library to yo
8282
```cpp
8383
#include <ack/ack.hpp>
8484

85-
// Calculate sum of 2 EC points on secp256k1 curve
85+
// Calculate sum of 2 EC points on secp256k1 curve using affine coordinates
8686
const auto p1 = ack::ec_curve::secp256k1.make_point( p1_x, p1_y );
8787
const auto p2 = ack::ec_curve::secp256k1.generate_point( "85d0c2e48955214783ecf50a4f041" );
8888
const auto p3 = p1 + p2;
8989

90-
// triple the p3 point
90+
// Triple the p3 point
9191
const auto p4 = p3 * 3;
9292

93-
// multiply the inverse of p4 by integer 0x73c5f6a67456ae48209b5a32d1b8
93+
// Multiply the inverse of p4 by integer 0x73c5f6a67456ae48209b5a32d1b8
9494
const auto p5 = -p4 * "73c5f6a67456ae48209b5a32d1b8";
95+
96+
// Generate 2 EC points on secp256r1 curve using Jacobi coordinates representation
97+
using secp256r1_t = decltype( ack::ec_curve::secp256r1 );
98+
using point_r1_jacobi = ack::ec_point_fp_jacobi<secp256r1_t>;
99+
100+
const auto p1 = ack::ec_curve::secp256k1.generate_point<point_r1_jacobi>( "5d0c2e48955214783ecf50a4f041" );
101+
const auto p2_affine = ack::ec_curve::secp256k1.make_point( p2_x, p2_y );
102+
const auto p2 = point_r1_jacobi( p2_affine );
103+
104+
// Calculate sum of 2 EC points on secp256r1 curve in Jacobi coordinates
105+
const auto p3 = p1 + p2;
106+
107+
// Double point p3
108+
const auto p4 = p3 * 2; // or p3.doubled();
109+
110+
// Verify point p4 is not identity and lies on the curve
111+
eosio::check( !p4.is_identity(), "invalid point" );
112+
eosio::check( p4.is_on_curve() , "invalid point" );
113+
eosio::check( p4.is_valid() , "invalid point" );
114+
115+
// Convert point p4 to affine coordinates
116+
const auto p4_affine = p4.to_affine();
95117

96118
// Verify secp256k1 ECDSA-SHA256 signature
97119
auto pub_point = ack::ec_curve::secp256k1.make_point( pubkey_x, pubkey_y );
@@ -139,11 +161,14 @@ If configured correctly, you should be able to add the antelope.ck library to yo
139161
// Do something...
140162
}
141163

164+
// Calculate SHA384
165+
hash384 mdsh384 = ack::sha384( byte_data );
166+
142167
// Calculate SHA3-384
143-
eosio::fixed_bytes<48> mdsh3 = ack::sha3_384( byte_data );
168+
hash384 mdsh3 = ack::sha3_384( byte_data );
144169

145170
// Calculate fixed size SHAKE-128 hash
146-
eosio::checksum160 mdshk128 = ack::shake128_fixed<20>( byte_data );
171+
hash160 mdshk128 = ack::shake128_fixed<20>( byte_data );
147172

148173
// calculate var-long SHAKE-256 hash
149174
bytes mdshk256 = ack::shake256( byte_data, /*hash_len=*/16 );

include/ack/bigint.hpp

+62-2
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
#include <bit>
3030
#include <cstdlib>
3131
#include <cstddef>
32+
#include <vector>
3233
#include <type_traits>
3334

3435
namespace ack {
@@ -1448,6 +1449,41 @@ namespace ack {
14481449
return data;
14491450
}
14501451

1452+
/**
1453+
* Converts this integer to non-adjacent form (NAF).
1454+
* @return NAF representation of this integer.
1455+
*/
1456+
[[nodiscard]] std::vector<char> to_naf() const
1457+
{
1458+
std::vector<char> nafv;
1459+
nafv.reserve( bit_length() + 1 );
1460+
auto num = *this;
1461+
while ( num > 0U ) {
1462+
if ( num.is_odd() ) {
1463+
int32_t nd;
1464+
(num % 4).get_int32( nd );
1465+
nd = 2 - nd;
1466+
nafv.push_back( nd );
1467+
num -= nd;
1468+
} else {
1469+
nafv.push_back( 0 );
1470+
}
1471+
num >>= 1;
1472+
}
1473+
return nafv;
1474+
}
1475+
1476+
/**
1477+
* Converts this integer to reversed non-adjacent form (NAF).
1478+
* @return reversed NAF representation of this integer.
1479+
*/
1480+
[[nodiscard]] inline std::vector<char> to_rnaf() const
1481+
{
1482+
auto naf = to_naf();
1483+
std::reverse(naf.begin(), naf.end());
1484+
return naf;
1485+
}
1486+
14511487
constexpr void clear()
14521488
{
14531489
*this = 0;
@@ -1616,6 +1652,30 @@ namespace ack {
16161652
return !is_odd();
16171653
}
16181654

1655+
/**
1656+
* Extracts integer as int32_t.
1657+
* Integer can be extracted only if the bit size of number is less than or equal to 32 bit integer.
1658+
*
1659+
* @param n - Reference of type int32_t to receive extracted integer.
1660+
* @return true if integer could be extracted otherwise false.
1661+
*/
1662+
constexpr bool get_int32(int32_t& n) const
1663+
{
1664+
static_assert( sizeof(word_t) == sizeof(uint32_t) );
1665+
if (word_length() > 1) {
1666+
return false;
1667+
}
1668+
1669+
n = 0;
1670+
if (word_length() > 0) {
1671+
n = buf_[0];
1672+
if ( is_negative() && n > 0 ) {
1673+
n = -n;
1674+
}
1675+
}
1676+
return true;
1677+
}
1678+
16191679
constexpr const word_t* get_word() const // get pointer to word data
16201680
{
16211681
return &buf_[0];
@@ -2470,13 +2530,13 @@ namespace ack {
24702530
*/
24712531
template<std::size_t MaxBitSize>
24722532
using fixed_bigint = bigint<fixed_word_buffer<get_word_size_from_bitsize(MaxBitSize)>>;
2473-
2533+
24742534
template <typename>
24752535
struct is_bigint : std::false_type {};
24762536

24772537
template <typename T>
24782538
struct is_bigint<bigint<T>> : std::true_type {};
2479-
2539+
24802540
template<typename T>
24812541
constexpr bool is_bigint_v = is_bigint<T>::value;
24822542
}

0 commit comments

Comments
 (0)