-
-
Notifications
You must be signed in to change notification settings - Fork 3.1k
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
[seraphis] seraphis_crypto: add seraphis transcript utility #8990
Conversation
96143ce
to
811e309
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good, but there is one thing that definitely needs to be changed (the signed integer code).
if (m_mode == Mode::SIMPLE) | ||
return; | ||
|
||
static_assert(sizeof(std::size_t) <= sizeof(std::uint64_t), ""); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
static_assert(std::numeric_limits<std::size_t>::max() <= std::numeric_limits<std::uint64_t>::max()`, "")
is probably the most accurate. Although, I'm not sure of any scenarios where your check fails.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I expect a LOT of old C/C++ code would break if these checks ever became invalid.
src/seraphis_crypto/sp_transcript.h
Outdated
{ | ||
// negative integer: byte{1} || varint(uint(abs(int_variable))) | ||
this->append_uint(1); | ||
this->append_uint(static_cast<std::uint64_t>(-signed_integer)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This can overflow if std::numeric_limits<T>::min()
and the platform is using 2s complement (the most common). I think this works on all platforms though:
using unsigned_type = std::make_unsigned<T>::type;
static_assert(sizeof(unsigned_type) <= sizeof(std::uint64_t), "");
this->append_uint(static_cast<unsigned_type>(signed_integer));
This stack overflow might be helpful.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah nice catch. Technically my approach is sound because it will only wrap to zero, which is treated as a positive integer normally so there is no malleability. However better to be absolutely correct here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh I didn't think of that. You'd have a positive and negative zero.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oops, I thought this wasn't submitted.
811e309
to
1a1caa5
Compare
@vtnerd could you re-review and potentially approve? |
src/seraphis_crypto/sp_transcript.h
Outdated
|
||
//local headers | ||
#include "crypto/crypto.h" | ||
#include "crypto/x25519.h" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can't find this header, is this new? The checks still pass, so I must be missing something.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh yeah x25519 is not PRd yet, I will remove that code from here and re-add it with the x25519 PR.
Summary
This is a PR in my 'upstreaming seraphis_lib project', it is not used anywhere yet.
src/seraphis_crypto
directory. Includes a dummy cpp file so cmake won't complain (will remove it once I have a cpp file to add).sp_transcript.h
toseraphis_crypto
.Explanation
In the current codebase, transcripting of crypto protocols is done manually which is verbose and inflexible. I wrote a transcripting utility that is quite ergonomic and has served me well in the seraphis library.
There are two modes
SpFSTranscript
: Fiat-Shamir transcript, includes labels, type flags, and type lengths. Suited for variable-length transcripts. Should be used for Fiat-Shamir challenges.SpKDFTranscript
: KDF transcript, does not include labels, type flags, or type lengths. Suited for short fixed-length transcripts (e.g. key derivations). In my seraphis library all uses of KDF transcripts are less than 128 bytes (or 256 bytes at least, can't remember).Example use: