-
Notifications
You must be signed in to change notification settings - Fork 168
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
Method SetIntString in the Scalar interface to create arbitrary large scalars from strings #534
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -6,6 +6,7 @@ import ( | |
"crypto/cipher" | ||
"encoding/hex" | ||
"errors" | ||
"fmt" | ||
"io" | ||
"math/big" | ||
|
||
|
@@ -173,6 +174,15 @@ func (i *Int) SetInt64(v int64) kyber.Scalar { | |
return i | ||
} | ||
|
||
func (i *Int) SetIntString(v string) (kyber.Scalar, error) { | ||
bigV := new(big.Int) | ||
bigV, ok := bigV.SetString(v, 0) | ||
if !ok { | ||
return nil, fmt.Errorf("unable to set string number: %v", v) | ||
} | ||
return i.Init(bigV, i.M), nil | ||
} | ||
|
||
Comment on lines
+177
to
+185
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Looking at this implementation I don't see why the code couldn't live in your own codebase as a helper function: you don't seem to need any internal or non-exported function to achieve this, no? Like you could do something like:
assuming you work with a fixed modulus, no? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks for the reply! I agree that touching the interface is contentious. And I didn't even consider the fact that other people using Kyber could have their own Scalar implementations, which now would have to be changed. The mod.Int struct is public and has the methods to create a scalar from any pair of big ints, as seen in Init. I suppose the bigger problem lies in having methods requiring specific Scalar implementations, contrary to what the signature indicates. But just adding the SetIntString method was my quick and easy solution for the problem. We could have the SetIntString method just in the edwards25519.scalar, instead of all scalars. It wouldn't force a change in the interface on one hand, on the other it would reveal more of the internals of edwards25519, because now the user that wants to create a scalar must know that specific implementation is used. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I understand your argument and I'm open to discussing it, albeit I would need a very convincing use case. At the moment, I don't see why the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I agree that there is nothing you can't do with SetBytes. I just find the SetIntString more user friendly. On that note, the Bytes array on big.Int is big endian, while the default byte order of the kyber scalars are little endian. Finally, while its not a problem in my use case, I think that using the Bytes method in big.Int and SetIntBytes of Scalar implementations might cause some performance hiccups. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. As others have said, I also think this is a very specific use-case and should be handled locally in your code. I think a There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. As the commit stands currently, the SetIntString method does not need the argument to be decimal. It can be decimal, hexadecimal, octal or even binary, as long as it has the appropriate prefix. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. OK, I didn't see it uses
|
||
// Int64 returns the int64 representation of the value. | ||
// If the value is not representable in an int64 the result is undefined. | ||
func (i *Int) Int64() int64 { | ||
|
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 guess my main worry with making the Scalar interface any bigger is that it'll break all implementations using custom scalars.
That being said we're en route to V4 so we could do it... Opinions @pierluca ?
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 share your concern, @AnomalRoil . Could you elaborate a little bit more about the use case, @pmcampones ?
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.
It says "string encoded integer value", which definitely looks like it should be done using
SetInt64
. Other possibilities I see:SetBigInt
which could use more than 64 bitsSetBytes
which already exists :)So I suppose this should be something like
SetInt64(strconv.Atoi())
or use theSetBytes
for bigger integers.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.
Maybe SetBigInt would be a better name for the method.
In the comment thread bellow we discussed using only SetBytes instead of the SetIntString.
I find using SetIntString a bit more convenient and less error prone than using SetBytes.