Imported Upstream version 4.8.0.309

Former-commit-id: 5f9c6ae75f295e057a7d2971f3a6df4656fa8850
This commit is contained in:
Xamarin Public Jenkins (auto-signing)
2016-11-10 13:04:39 +00:00
parent ee1447783b
commit 94b2861243
4912 changed files with 390737 additions and 49310 deletions

View File

@@ -0,0 +1,14 @@
include_directories(../../include)
add_executable(
bssl_shim
async_bio.cc
bssl_shim.cc
packeted_bio.cc
test_config.cc
$<TARGET_OBJECTS:test_support>
)
target_link_libraries(bssl_shim ssl crypto)

35
external/boringssl/ssl/test/README.md vendored Normal file
View File

@@ -0,0 +1,35 @@
# BoringSSL SSL Tests
This directory contains BoringSSL's protocol-level test suite.
Testing a TLS implementation can be difficult. We need to produce invalid but
sufficiently correct handshakes to get our implementation close to its edge
cases. TLS's cryptographic steps mean we cannot use a transcript and effectively
need a TLS implementation on the other end. But we do not wish to litter
BoringSSL with options for bugs to test against.
Instead, we use a fork of the Go `crypto/tls` package, heavily patched with
configurable bugs. This code, along with a test suite and harness written in Go,
lives in the `runner` directory. The harness runs BoringSSL via a C/C++ shim
binary which lives in this directory. All communication with the shim binary
occurs with command-line flags, sockets, and standard I/O.
This strategy also ensures we always test against a second implementation. All
features should be implemented twice, once in C for BoringSSL and once in Go for
testing. If possible, the Go code should be suitable for potentially
upstreaming. However, sometimes test code has different needs. For example, our
test DTLS code enforces strict ordering on sequence numbers and has controlled
packet drop simulation.
To run the tests manually, run `go test` from the `runner` directory. It takes
command-line flags found at the top of `runner/runner.go`. The `-help` option
also works after using `go test -c` to make a `runner.test` binary first.
If adding a new test, these files may be a good starting point:
* `runner/runner.go`: the test harness and all the individual tests.
* `runner/common.go`: contains the `Config` and `ProtocolBugs` struct which
control the Go TLS implementation's behavior.
* `test_config.h`, `test_config.cc`: the command-line flags which control the
shim's behavior.
* `bssl_shim.cc`: the shim binary itself.

188
external/boringssl/ssl/test/async_bio.cc vendored Normal file
View File

@@ -0,0 +1,188 @@
/* Copyright (c) 2014, Google Inc.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
#include "async_bio.h"
#include <errno.h>
#include <string.h>
#include <openssl/mem.h>
namespace {
extern const BIO_METHOD g_async_bio_method;
struct AsyncBio {
bool datagram;
bool enforce_write_quota;
size_t read_quota;
size_t write_quota;
};
AsyncBio *GetData(BIO *bio) {
if (bio->method != &g_async_bio_method) {
return NULL;
}
return (AsyncBio *)bio->ptr;
}
static int AsyncWrite(BIO *bio, const char *in, int inl) {
AsyncBio *a = GetData(bio);
if (a == NULL || bio->next_bio == NULL) {
return 0;
}
if (!a->enforce_write_quota) {
return BIO_write(bio->next_bio, in, inl);
}
BIO_clear_retry_flags(bio);
if (a->write_quota == 0) {
BIO_set_retry_write(bio);
errno = EAGAIN;
return -1;
}
if (!a->datagram && (size_t)inl > a->write_quota) {
inl = a->write_quota;
}
int ret = BIO_write(bio->next_bio, in, inl);
if (ret <= 0) {
BIO_copy_next_retry(bio);
} else {
a->write_quota -= (a->datagram ? 1 : ret);
}
return ret;
}
static int AsyncRead(BIO *bio, char *out, int outl) {
AsyncBio *a = GetData(bio);
if (a == NULL || bio->next_bio == NULL) {
return 0;
}
BIO_clear_retry_flags(bio);
if (a->read_quota == 0) {
BIO_set_retry_read(bio);
errno = EAGAIN;
return -1;
}
if (!a->datagram && (size_t)outl > a->read_quota) {
outl = a->read_quota;
}
int ret = BIO_read(bio->next_bio, out, outl);
if (ret <= 0) {
BIO_copy_next_retry(bio);
} else {
a->read_quota -= (a->datagram ? 1 : ret);
}
return ret;
}
static long AsyncCtrl(BIO *bio, int cmd, long num, void *ptr) {
if (bio->next_bio == NULL) {
return 0;
}
BIO_clear_retry_flags(bio);
int ret = BIO_ctrl(bio->next_bio, cmd, num, ptr);
BIO_copy_next_retry(bio);
return ret;
}
static int AsyncNew(BIO *bio) {
AsyncBio *a = (AsyncBio *)OPENSSL_malloc(sizeof(*a));
if (a == NULL) {
return 0;
}
memset(a, 0, sizeof(*a));
a->enforce_write_quota = true;
bio->init = 1;
bio->ptr = (char *)a;
return 1;
}
static int AsyncFree(BIO *bio) {
if (bio == NULL) {
return 0;
}
OPENSSL_free(bio->ptr);
bio->ptr = NULL;
bio->init = 0;
bio->flags = 0;
return 1;
}
static long AsyncCallbackCtrl(BIO *bio, int cmd, bio_info_cb fp) {
if (bio->next_bio == NULL) {
return 0;
}
return BIO_callback_ctrl(bio->next_bio, cmd, fp);
}
const BIO_METHOD g_async_bio_method = {
BIO_TYPE_FILTER,
"async bio",
AsyncWrite,
AsyncRead,
NULL /* puts */,
NULL /* gets */,
AsyncCtrl,
AsyncNew,
AsyncFree,
AsyncCallbackCtrl,
};
} // namespace
ScopedBIO AsyncBioCreate() {
return ScopedBIO(BIO_new(&g_async_bio_method));
}
ScopedBIO AsyncBioCreateDatagram() {
ScopedBIO ret(BIO_new(&g_async_bio_method));
if (!ret) {
return nullptr;
}
GetData(ret.get())->datagram = true;
return ret;
}
void AsyncBioAllowRead(BIO *bio, size_t count) {
AsyncBio *a = GetData(bio);
if (a == NULL) {
return;
}
a->read_quota += count;
}
void AsyncBioAllowWrite(BIO *bio, size_t count) {
AsyncBio *a = GetData(bio);
if (a == NULL) {
return;
}
a->write_quota += count;
}
void AsyncBioEnforceWriteQuota(BIO *bio, bool enforce) {
AsyncBio *a = GetData(bio);
if (a == NULL) {
return;
}
a->enforce_write_quota = enforce;
}

45
external/boringssl/ssl/test/async_bio.h vendored Normal file
View File

@@ -0,0 +1,45 @@
/* Copyright (c) 2014, Google Inc.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
#ifndef HEADER_ASYNC_BIO
#define HEADER_ASYNC_BIO
#include <openssl/bio.h>
#include "../../crypto/test/scoped_types.h"
// AsyncBioCreate creates a filter BIO for testing asynchronous state
// machines which consume a stream socket. Reads and writes will fail
// and return EAGAIN unless explicitly allowed. Each async BIO has a
// read quota and a write quota. Initially both are zero. As each is
// incremented, bytes are allowed to flow through the BIO.
ScopedBIO AsyncBioCreate();
// AsyncBioCreateDatagram creates a filter BIO for testing for
// asynchronous state machines which consume datagram sockets. The read
// and write quota count in packets rather than bytes.
ScopedBIO AsyncBioCreateDatagram();
// AsyncBioAllowRead increments |bio|'s read quota by |count|.
void AsyncBioAllowRead(BIO *bio, size_t count);
// AsyncBioAllowWrite increments |bio|'s write quota by |count|.
void AsyncBioAllowWrite(BIO *bio, size_t count);
// AsyncBioEnforceWriteQuota configures where |bio| enforces its write quota.
void AsyncBioEnforceWriteQuota(BIO *bio, bool enforce);
#endif // HEADER_ASYNC_BIO

1598
external/boringssl/ssl/test/bssl_shim.cc vendored Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,304 @@
/* Copyright (c) 2014, Google Inc.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
#include "packeted_bio.h"
#include <assert.h>
#include <limits.h>
#include <stdio.h>
#include <string.h>
#include <openssl/mem.h>
namespace {
extern const BIO_METHOD g_packeted_bio_method;
const uint8_t kOpcodePacket = 'P';
const uint8_t kOpcodeTimeout = 'T';
const uint8_t kOpcodeTimeoutAck = 't';
struct PacketedBio {
explicit PacketedBio(bool advance_clock_arg)
: advance_clock(advance_clock_arg) {
memset(&timeout, 0, sizeof(timeout));
memset(&clock, 0, sizeof(clock));
memset(&read_deadline, 0, sizeof(read_deadline));
}
bool HasTimeout() const {
return timeout.tv_sec != 0 || timeout.tv_usec != 0;
}
bool CanRead() const {
if (read_deadline.tv_sec == 0 && read_deadline.tv_usec == 0) {
return true;
}
if (clock.tv_sec == read_deadline.tv_sec) {
return clock.tv_usec < read_deadline.tv_usec;
}
return clock.tv_sec < read_deadline.tv_sec;
}
timeval timeout;
timeval clock;
timeval read_deadline;
bool advance_clock;
};
PacketedBio *GetData(BIO *bio) {
if (bio->method != &g_packeted_bio_method) {
return NULL;
}
return (PacketedBio *)bio->ptr;
}
const PacketedBio *GetData(const BIO *bio) {
return GetData(const_cast<BIO*>(bio));
}
// ReadAll reads |len| bytes from |bio| into |out|. It returns 1 on success and
// 0 or -1 on error.
static int ReadAll(BIO *bio, uint8_t *out, size_t len) {
while (len > 0) {
int chunk_len = INT_MAX;
if (len <= INT_MAX) {
chunk_len = (int)len;
}
int ret = BIO_read(bio, out, chunk_len);
if (ret <= 0) {
return ret;
}
out += ret;
len -= ret;
}
return 1;
}
static int PacketedWrite(BIO *bio, const char *in, int inl) {
if (bio->next_bio == NULL) {
return 0;
}
BIO_clear_retry_flags(bio);
// Write the header.
uint8_t header[5];
header[0] = kOpcodePacket;
header[1] = (inl >> 24) & 0xff;
header[2] = (inl >> 16) & 0xff;
header[3] = (inl >> 8) & 0xff;
header[4] = inl & 0xff;
int ret = BIO_write(bio->next_bio, header, sizeof(header));
if (ret <= 0) {
BIO_copy_next_retry(bio);
return ret;
}
// Write the buffer.
ret = BIO_write(bio->next_bio, in, inl);
if (ret < 0 || (inl > 0 && ret == 0)) {
BIO_copy_next_retry(bio);
return ret;
}
assert(ret == inl);
return ret;
}
static int PacketedRead(BIO *bio, char *out, int outl) {
PacketedBio *data = GetData(bio);
if (bio->next_bio == NULL) {
return 0;
}
BIO_clear_retry_flags(bio);
for (;;) {
// Check if the read deadline has passed.
if (!data->CanRead()) {
BIO_set_retry_read(bio);
return -1;
}
// Read the opcode.
uint8_t opcode;
int ret = ReadAll(bio->next_bio, &opcode, sizeof(opcode));
if (ret <= 0) {
BIO_copy_next_retry(bio);
return ret;
}
if (opcode == kOpcodeTimeout) {
// The caller is required to advance any pending timeouts before
// continuing.
if (data->HasTimeout()) {
fprintf(stderr, "Unprocessed timeout!\n");
return -1;
}
// Process the timeout.
uint8_t buf[8];
ret = ReadAll(bio->next_bio, buf, sizeof(buf));
if (ret <= 0) {
BIO_copy_next_retry(bio);
return ret;
}
uint64_t timeout = (static_cast<uint64_t>(buf[0]) << 56) |
(static_cast<uint64_t>(buf[1]) << 48) |
(static_cast<uint64_t>(buf[2]) << 40) |
(static_cast<uint64_t>(buf[3]) << 32) |
(static_cast<uint64_t>(buf[4]) << 24) |
(static_cast<uint64_t>(buf[5]) << 16) |
(static_cast<uint64_t>(buf[6]) << 8) |
static_cast<uint64_t>(buf[7]);
timeout /= 1000; // Convert nanoseconds to microseconds.
data->timeout.tv_usec = timeout % 1000000;
data->timeout.tv_sec = timeout / 1000000;
// Send an ACK to the peer.
ret = BIO_write(bio->next_bio, &kOpcodeTimeoutAck, 1);
if (ret <= 0) {
return ret;
}
assert(ret == 1);
if (!data->advance_clock) {
// Signal to the caller to retry the read, after advancing the clock.
BIO_set_retry_read(bio);
return -1;
}
PacketedBioAdvanceClock(bio);
continue;
}
if (opcode != kOpcodePacket) {
fprintf(stderr, "Unknown opcode, %u\n", opcode);
return -1;
}
// Read the length prefix.
uint8_t len_bytes[4];
ret = ReadAll(bio->next_bio, len_bytes, sizeof(len_bytes));
if (ret <= 0) {
BIO_copy_next_retry(bio);
return ret;
}
uint32_t len = (len_bytes[0] << 24) | (len_bytes[1] << 16) |
(len_bytes[2] << 8) | len_bytes[3];
uint8_t *buf = (uint8_t *)OPENSSL_malloc(len);
if (buf == NULL) {
return -1;
}
ret = ReadAll(bio->next_bio, buf, len);
if (ret <= 0) {
fprintf(stderr, "Packeted BIO was truncated\n");
return -1;
}
if (outl > (int)len) {
outl = len;
}
memcpy(out, buf, outl);
OPENSSL_free(buf);
return outl;
}
}
static long PacketedCtrl(BIO *bio, int cmd, long num, void *ptr) {
if (cmd == BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT) {
memcpy(&GetData(bio)->read_deadline, ptr, sizeof(timeval));
return 1;
}
if (bio->next_bio == NULL) {
return 0;
}
BIO_clear_retry_flags(bio);
int ret = BIO_ctrl(bio->next_bio, cmd, num, ptr);
BIO_copy_next_retry(bio);
return ret;
}
static int PacketedNew(BIO *bio) {
bio->init = 1;
return 1;
}
static int PacketedFree(BIO *bio) {
if (bio == NULL) {
return 0;
}
delete GetData(bio);
bio->init = 0;
return 1;
}
static long PacketedCallbackCtrl(BIO *bio, int cmd, bio_info_cb fp) {
if (bio->next_bio == NULL) {
return 0;
}
return BIO_callback_ctrl(bio->next_bio, cmd, fp);
}
const BIO_METHOD g_packeted_bio_method = {
BIO_TYPE_FILTER,
"packeted bio",
PacketedWrite,
PacketedRead,
NULL /* puts */,
NULL /* gets */,
PacketedCtrl,
PacketedNew,
PacketedFree,
PacketedCallbackCtrl,
};
} // namespace
ScopedBIO PacketedBioCreate(bool advance_clock) {
ScopedBIO bio(BIO_new(&g_packeted_bio_method));
if (!bio) {
return nullptr;
}
bio->ptr = new PacketedBio(advance_clock);
return bio;
}
timeval PacketedBioGetClock(const BIO *bio) {
return GetData(bio)->clock;
}
bool PacketedBioAdvanceClock(BIO *bio) {
PacketedBio *data = GetData(bio);
if (data == nullptr) {
return false;
}
if (!data->HasTimeout()) {
return false;
}
data->clock.tv_usec += data->timeout.tv_usec;
data->clock.tv_sec += data->clock.tv_usec / 1000000;
data->clock.tv_usec %= 1000000;
data->clock.tv_sec += data->timeout.tv_sec;
memset(&data->timeout, 0, sizeof(data->timeout));
return true;
}

View File

@@ -0,0 +1,51 @@
/* Copyright (c) 2014, Google Inc.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
#ifndef HEADER_PACKETED_BIO
#define HEADER_PACKETED_BIO
#include <openssl/base.h>
#include <openssl/bio.h>
#include "../../crypto/test/scoped_types.h"
#if defined(OPENSSL_WINDOWS)
OPENSSL_MSVC_PRAGMA(warning(push, 3))
#include <winsock2.h>
OPENSSL_MSVC_PRAGMA(warning(pop))
#else
#include <sys/time.h>
#endif
// PacketedBioCreate creates a filter BIO which implements a reliable in-order
// blocking datagram socket. It internally maintains a clock and honors
// |BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT| based on it.
//
// During a |BIO_read|, the peer may signal the filter BIO to simulate a
// timeout. If |advance_clock| is true, it automatically advances the clock and
// continues reading, subject to the read deadline. Otherwise, it fails
// immediately. The caller must then call |PacketedBioAdvanceClock| before
// retrying |BIO_read|.
ScopedBIO PacketedBioCreate(bool advance_clock);
// PacketedBioGetClock returns the current time for |bio|.
timeval PacketedBioGetClock(const BIO *bio);
// PacketedBioAdvanceClock advances |bio|'s internal clock and returns true if
// there is a pending timeout. Otherwise, it returns false.
bool PacketedBioAdvanceClock(BIO *bio);
#endif // HEADER_PACKETED_BIO

View File

@@ -0,0 +1,78 @@
// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package runner
import "strconv"
type alert uint8
const (
// alert level
alertLevelWarning = 1
alertLevelError = 2
)
const (
alertCloseNotify alert = 0
alertUnexpectedMessage alert = 10
alertBadRecordMAC alert = 20
alertDecryptionFailed alert = 21
alertRecordOverflow alert = 22
alertDecompressionFailure alert = 30
alertHandshakeFailure alert = 40
alertNoCertficate alert = 41
alertBadCertificate alert = 42
alertUnsupportedCertificate alert = 43
alertCertificateRevoked alert = 44
alertCertificateExpired alert = 45
alertCertificateUnknown alert = 46
alertIllegalParameter alert = 47
alertUnknownCA alert = 48
alertAccessDenied alert = 49
alertDecodeError alert = 50
alertDecryptError alert = 51
alertProtocolVersion alert = 70
alertInsufficientSecurity alert = 71
alertInternalError alert = 80
alertUserCanceled alert = 90
alertNoRenegotiation alert = 100
)
var alertText = map[alert]string{
alertCloseNotify: "close notify",
alertUnexpectedMessage: "unexpected message",
alertBadRecordMAC: "bad record MAC",
alertDecryptionFailed: "decryption failed",
alertRecordOverflow: "record overflow",
alertDecompressionFailure: "decompression failure",
alertHandshakeFailure: "handshake failure",
alertBadCertificate: "bad certificate",
alertUnsupportedCertificate: "unsupported certificate",
alertCertificateRevoked: "revoked certificate",
alertCertificateExpired: "expired certificate",
alertCertificateUnknown: "unknown certificate",
alertIllegalParameter: "illegal parameter",
alertUnknownCA: "unknown certificate authority",
alertAccessDenied: "access denied",
alertDecodeError: "error decoding message",
alertDecryptError: "error decrypting message",
alertProtocolVersion: "protocol version not supported",
alertInsufficientSecurity: "insufficient security level",
alertInternalError: "internal error",
alertUserCanceled: "user canceled",
alertNoRenegotiation: "no renegotiation",
}
func (e alert) String() string {
s, ok := alertText[e]
if ok {
return s
}
return "alert(" + strconv.Itoa(int(e)) + ")"
}
func (e alert) Error() string {
return e.String()
}

View File

@@ -0,0 +1,15 @@
-----BEGIN CERTIFICATE-----
MIICWDCCAcGgAwIBAgIJAPuwTC6rEJsMMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNV
BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX
aWRnaXRzIFB0eSBMdGQwHhcNMTQwNDIzMjA1MDQwWhcNMTcwNDIyMjA1MDQwWjBF
MQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50
ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKB
gQDYK8imMuRi/03z0K1Zi0WnvfFHvwlYeyK9Na6XJYaUoIDAtB92kWdGMdAQhLci
HnAjkXLI6W15OoV3gA/ElRZ1xUpxTMhjP6PyY5wqT5r6y8FxbiiFKKAnHmUcrgfV
W28tQ+0rkLGMryRtrukXOgXBv7gcrmU7G1jC2a7WqmeI8QIDAQABo1AwTjAdBgNV
HQ4EFgQUi3XVrMsIvg4fZbf6Vr5sp3Xaha8wHwYDVR0jBBgwFoAUi3XVrMsIvg4f
Zbf6Vr5sp3Xaha8wDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQUFAAOBgQA76Hht
ldY9avcTGSwbwoiuIqv0jTL1fHFnzy3RHMLDh+Lpvolc5DSrSJHCP5WuK0eeJXhr
T5oQpHL9z/cCDLAKCKRa4uV0fhEdOWBqyR9p8y5jJtye72t6CuFUV5iqcpF4BH4f
j2VNHwsSrJwkD4QUGlUtH7vwnQmyCFxZMmWAJg==
-----END CERTIFICATE-----

View File

@@ -0,0 +1,235 @@
// Copyright (c) 2016, Google Inc.
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
// SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
// OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
package runner
import (
"crypto/cipher"
"crypto/subtle"
"encoding/binary"
"errors"
"./poly1305"
)
// See RFC 7539.
func leftRotate(a uint32, n uint) uint32 {
return (a << n) | (a >> (32 - n))
}
func chaChaQuarterRound(state *[16]uint32, a, b, c, d int) {
state[a] += state[b]
state[d] = leftRotate(state[d]^state[a], 16)
state[c] += state[d]
state[b] = leftRotate(state[b]^state[c], 12)
state[a] += state[b]
state[d] = leftRotate(state[d]^state[a], 8)
state[c] += state[d]
state[b] = leftRotate(state[b]^state[c], 7)
}
func chaCha20Block(state *[16]uint32, out []byte) {
var workingState [16]uint32
copy(workingState[:], state[:])
for i := 0; i < 10; i++ {
chaChaQuarterRound(&workingState, 0, 4, 8, 12)
chaChaQuarterRound(&workingState, 1, 5, 9, 13)
chaChaQuarterRound(&workingState, 2, 6, 10, 14)
chaChaQuarterRound(&workingState, 3, 7, 11, 15)
chaChaQuarterRound(&workingState, 0, 5, 10, 15)
chaChaQuarterRound(&workingState, 1, 6, 11, 12)
chaChaQuarterRound(&workingState, 2, 7, 8, 13)
chaChaQuarterRound(&workingState, 3, 4, 9, 14)
}
for i := 0; i < 16; i++ {
binary.LittleEndian.PutUint32(out[i*4:i*4+4], workingState[i]+state[i])
}
}
// sliceForAppend takes a slice and a requested number of bytes. It returns a
// slice with the contents of the given slice followed by that many bytes and a
// second slice that aliases into it and contains only the extra bytes. If the
// original slice has sufficient capacity then no allocation is performed.
func sliceForAppend(in []byte, n int) (head, tail []byte) {
if total := len(in) + n; cap(in) >= total {
head = in[:total]
} else {
head = make([]byte, total)
copy(head, in)
}
tail = head[len(in):]
return
}
func chaCha20(out, in, key, nonce []byte, counter uint64) {
var state [16]uint32
state[0] = 0x61707865
state[1] = 0x3320646e
state[2] = 0x79622d32
state[3] = 0x6b206574
for i := 0; i < 8; i++ {
state[4+i] = binary.LittleEndian.Uint32(key[i*4 : i*4+4])
}
switch len(nonce) {
case 8:
state[14] = binary.LittleEndian.Uint32(nonce[0:4])
state[15] = binary.LittleEndian.Uint32(nonce[4:8])
case 12:
state[13] = binary.LittleEndian.Uint32(nonce[0:4])
state[14] = binary.LittleEndian.Uint32(nonce[4:8])
state[15] = binary.LittleEndian.Uint32(nonce[8:12])
default:
panic("bad nonce length")
}
for i := 0; i < len(in); i += 64 {
state[12] = uint32(counter)
var tmp [64]byte
chaCha20Block(&state, tmp[:])
count := 64
if len(in)-i < count {
count = len(in) - i
}
for j := 0; j < count; j++ {
out[i+j] = in[i+j] ^ tmp[j]
}
counter++
}
}
// chaCha20Poly1305 implements the AEAD from
// RFC 7539 and draft-agl-tls-chacha20poly1305-04.
type chaCha20Poly1305 struct {
key [32]byte
// oldMode, if true, indicates that the draft spec should be
// implemented rather than the final, RFC version.
oldMode bool
}
func newChaCha20Poly1305(key []byte) (cipher.AEAD, error) {
if len(key) != 32 {
return nil, errors.New("bad key length")
}
aead := new(chaCha20Poly1305)
copy(aead.key[:], key)
return aead, nil
}
func newChaCha20Poly1305Old(key []byte) (cipher.AEAD, error) {
if len(key) != 32 {
return nil, errors.New("bad key length")
}
aead := &chaCha20Poly1305{
oldMode: true,
}
copy(aead.key[:], key)
return aead, nil
}
func (c *chaCha20Poly1305) NonceSize() int {
if c.oldMode {
return 8
} else {
return 12
}
}
func (c *chaCha20Poly1305) Overhead() int { return 16 }
func (c *chaCha20Poly1305) poly1305(tag *[16]byte, nonce, ciphertext, additionalData []byte) {
input := make([]byte, 0, len(additionalData)+15+len(ciphertext)+15+8+8)
input = append(input, additionalData...)
var zeros [15]byte
if pad := len(input) % 16; pad != 0 {
input = append(input, zeros[:16-pad]...)
}
input = append(input, ciphertext...)
if pad := len(input) % 16; pad != 0 {
input = append(input, zeros[:16-pad]...)
}
input, out := sliceForAppend(input, 8)
binary.LittleEndian.PutUint64(out, uint64(len(additionalData)))
input, out = sliceForAppend(input, 8)
binary.LittleEndian.PutUint64(out, uint64(len(ciphertext)))
var poly1305Key [32]byte
chaCha20(poly1305Key[:], poly1305Key[:], c.key[:], nonce, 0)
poly1305.Sum(tag, input, &poly1305Key)
}
func (c *chaCha20Poly1305) poly1305Old(tag *[16]byte, nonce, ciphertext, additionalData []byte) {
input := make([]byte, 0, len(additionalData)+8+len(ciphertext)+8)
input = append(input, additionalData...)
input, out := sliceForAppend(input, 8)
binary.LittleEndian.PutUint64(out, uint64(len(additionalData)))
input = append(input, ciphertext...)
input, out = sliceForAppend(input, 8)
binary.LittleEndian.PutUint64(out, uint64(len(ciphertext)))
var poly1305Key [32]byte
chaCha20(poly1305Key[:], poly1305Key[:], c.key[:], nonce, 0)
poly1305.Sum(tag, input, &poly1305Key)
}
func (c *chaCha20Poly1305) Seal(dst, nonce, plaintext, additionalData []byte) []byte {
if len(nonce) != c.NonceSize() {
panic("Bad nonce length")
}
ret, out := sliceForAppend(dst, len(plaintext)+16)
chaCha20(out[:len(plaintext)], plaintext, c.key[:], nonce, 1)
var tag [16]byte
if c.oldMode {
c.poly1305Old(&tag, nonce, out[:len(plaintext)], additionalData)
} else {
c.poly1305(&tag, nonce, out[:len(plaintext)], additionalData)
}
copy(out[len(plaintext):], tag[:])
return ret
}
func (c *chaCha20Poly1305) Open(dst, nonce, ciphertext, additionalData []byte) ([]byte, error) {
if len(nonce) != c.NonceSize() {
panic("Bad nonce length")
}
if len(ciphertext) < 16 {
return nil, errors.New("chacha20: message authentication failed")
}
plaintextLen := len(ciphertext) - 16
var tag [16]byte
if c.oldMode {
c.poly1305Old(&tag, nonce, ciphertext[:plaintextLen], additionalData)
} else {
c.poly1305(&tag, nonce, ciphertext[:plaintextLen], additionalData)
}
if subtle.ConstantTimeCompare(tag[:], ciphertext[plaintextLen:]) != 1 {
return nil, errors.New("chacha20: message authentication failed")
}
ret, out := sliceForAppend(dst, plaintextLen)
chaCha20(out, ciphertext[:plaintextLen], c.key[:], nonce, 1)
return ret, nil
}

View File

@@ -0,0 +1,176 @@
// Copyright (c) 2016, Google Inc.
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
// SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
// OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
package runner
import (
"bytes"
"encoding/hex"
"testing"
)
// See RFC 7539, section 2.1.1.
func TestChaChaQuarterRound(t *testing.T) {
state := [16]uint32{0x11111111, 0x01020304, 0x9b8d6f43, 0x01234567}
chaChaQuarterRound(&state, 0, 1, 2, 3)
a, b, c, d := state[0], state[1], state[2], state[3]
if a != 0xea2a92f4 || b != 0xcb1cf8ce || c != 0x4581472e || d != 0x5881c4bb {
t.Errorf("Incorrect results: %x", state)
}
}
// See RFC 7539, section 2.2.1.
func TestChaChaQuarterRoundState(t *testing.T) {
state := [16]uint32{
0x879531e0, 0xc5ecf37d, 0x516461b1, 0xc9a62f8a,
0x44c20ef3, 0x3390af7f, 0xd9fc690b, 0x2a5f714c,
0x53372767, 0xb00a5631, 0x974c541a, 0x359e9963,
0x5c971061, 0x3d631689, 0x2098d9d6, 0x91dbd320,
}
chaChaQuarterRound(&state, 2, 7, 8, 13)
expected := [16]uint32{
0x879531e0, 0xc5ecf37d, 0xbdb886dc, 0xc9a62f8a,
0x44c20ef3, 0x3390af7f, 0xd9fc690b, 0xcfacafd2,
0xe46bea80, 0xb00a5631, 0x974c541a, 0x359e9963,
0x5c971061, 0xccc07c79, 0x2098d9d6, 0x91dbd320,
}
for i := range state {
if state[i] != expected[i] {
t.Errorf("Mismatch at %d: %x vs %x", i, state, expected)
}
}
}
// See RFC 7539, section 2.3.2.
func TestChaCha20Block(t *testing.T) {
state := [16]uint32{
0x61707865, 0x3320646e, 0x79622d32, 0x6b206574,
0x03020100, 0x07060504, 0x0b0a0908, 0x0f0e0d0c,
0x13121110, 0x17161514, 0x1b1a1918, 0x1f1e1d1c,
0x00000001, 0x09000000, 0x4a000000, 0x00000000,
}
out := make([]byte, 64)
chaCha20Block(&state, out)
expected := []byte{
0x10, 0xf1, 0xe7, 0xe4, 0xd1, 0x3b, 0x59, 0x15,
0x50, 0x0f, 0xdd, 0x1f, 0xa3, 0x20, 0x71, 0xc4,
0xc7, 0xd1, 0xf4, 0xc7, 0x33, 0xc0, 0x68, 0x03,
0x04, 0x22, 0xaa, 0x9a, 0xc3, 0xd4, 0x6c, 0x4e,
0xd2, 0x82, 0x64, 0x46, 0x07, 0x9f, 0xaa, 0x09,
0x14, 0xc2, 0xd7, 0x05, 0xd9, 0x8b, 0x02, 0xa2,
0xb5, 0x12, 0x9c, 0xd1, 0xde, 0x16, 0x4e, 0xb9,
0xcb, 0xd0, 0x83, 0xe8, 0xa2, 0x50, 0x3c, 0x4e,
}
if !bytes.Equal(out, expected) {
t.Errorf("Got %x, wanted %x", out, expected)
}
}
func decodeHexOrPanic(in string) []byte {
out, err := hex.DecodeString(in)
if err != nil {
panic(err)
}
return out
}
// See draft-agl-tls-chacha20poly1305-04, section 7.
func TestChaCha20Poly1305Old(t *testing.T) {
key := decodeHexOrPanic("4290bcb154173531f314af57f3be3b5006da371ece272afa1b5dbdd1100a1007")
input := decodeHexOrPanic("86d09974840bded2a5ca")
nonce := decodeHexOrPanic("cd7cf67be39c794a")
ad := decodeHexOrPanic("87e229d4500845a079c0")
output := decodeHexOrPanic("e3e446f7ede9a19b62a4677dabf4e3d24b876bb284753896e1d6")
aead, err := newChaCha20Poly1305Old(key)
if err != nil {
t.Fatal(err)
}
out, err := aead.Open(nil, nonce, output, ad)
if err != nil {
t.Errorf("Open failed: %s", err)
} else if !bytes.Equal(out, input) {
t.Errorf("Open gave %x, wanted %x", out, input)
}
out = aead.Seal(nil, nonce, input, ad)
if !bytes.Equal(out, output) {
t.Errorf("Open gave %x, wanted %x", out, output)
}
out[0]++
_, err = aead.Open(nil, nonce, out, ad)
if err == nil {
t.Errorf("Open on malformed data unexpectedly succeeded")
}
}
var chaCha20Poly1305TestVectors = []struct {
key, input, nonce, ad, output string
}{
{
// See RFC 7539, section 2.8.2.
key: "808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f",
input: "4c616469657320616e642047656e746c656d656e206f662074686520636c617373206f66202739393a204966204920636f756c64206f6666657220796f75206f6e6c79206f6e652074697020666f7220746865206675747572652c2073756e73637265656e20776f756c642062652069742e",
nonce: "070000004041424344454647",
ad: "50515253c0c1c2c3c4c5c6c7",
output: "d31a8d34648e60db7b86afbc53ef7ec2a4aded51296e08fea9e2b5a736ee62d63dbea45e8ca9671282fafb69da92728b1a71de0a9e060b2905d6a5b67ecd3b3692ddbd7f2d778b8c9803aee328091b58fab324e4fad675945585808b4831d7bc3ff4def08e4b7a9de576d26586cec64b61161ae10b594f09e26a7e902ecbd0600691",
},
{
// See RFC 7539, section A.5.
key: "1c9240a5eb55d38af333888604f6b5f0473917c1402b80099dca5cbc207075c0",
input: "496e7465726e65742d4472616674732061726520647261667420646f63756d656e74732076616c696420666f722061206d6178696d756d206f6620736978206d6f6e74687320616e64206d617920626520757064617465642c207265706c616365642c206f72206f62736f6c65746564206279206f7468657220646f63756d656e747320617420616e792074696d652e20497420697320696e617070726f70726961746520746f2075736520496e7465726e65742d447261667473206173207265666572656e6365206d6174657269616c206f7220746f2063697465207468656d206f74686572207468616e206173202fe2809c776f726b20696e2070726f67726573732e2fe2809d",
nonce: "000000000102030405060708",
ad: "f33388860000000000004e91",
output: "64a0861575861af460f062c79be643bd5e805cfd345cf389f108670ac76c8cb24c6cfc18755d43eea09ee94e382d26b0bdb7b73c321b0100d4f03b7f355894cf332f830e710b97ce98c8a84abd0b948114ad176e008d33bd60f982b1ff37c8559797a06ef4f0ef61c186324e2b3506383606907b6a7c02b0f9f6157b53c867e4b9166c767b804d46a59b5216cde7a4e99040c5a40433225ee282a1b0a06c523eaf4534d7f83fa1155b0047718cbc546a0d072b04b3564eea1b422273f548271a0bb2316053fa76991955ebd63159434ecebb4e466dae5a1073a6727627097a1049e617d91d361094fa68f0ff77987130305beaba2eda04df997b714d6c6f2c29a6ad5cb4022b02709beead9d67890cbb22392336fea1851f38",
},
}
// See draft-agl-tls-chacha20poly1305-04, section 7.
func TestChaCha20Poly1305(t *testing.T) {
for i, tt := range chaCha20Poly1305TestVectors {
key := decodeHexOrPanic(tt.key)
input := decodeHexOrPanic(tt.input)
nonce := decodeHexOrPanic(tt.nonce)
ad := decodeHexOrPanic(tt.ad)
output := decodeHexOrPanic(tt.output)
aead, err := newChaCha20Poly1305(key)
if err != nil {
t.Fatal(err)
}
out, err := aead.Open(nil, nonce, output, ad)
if err != nil {
t.Errorf("%d. Open failed: %s", i, err)
} else if !bytes.Equal(out, input) {
t.Errorf("%d. Open gave %x, wanted %x", i, out, input)
}
out = aead.Seal(nil, nonce, input, ad)
if !bytes.Equal(out, output) {
t.Errorf("%d. Open gave %x, wanted %x", i, out, output)
}
out[0]++
_, err = aead.Open(nil, nonce, out, ad)
if err == nil {
t.Errorf("%d. Open on malformed data unexpectedly succeeded", i)
}
}
}

View File

@@ -0,0 +1,5 @@
-----BEGIN EC PRIVATE KEY-----
MHcCAQEEIPwxu50c7LEhVNRYJFRWBUnoaz7JSos96T5hBp4rjyptoAoGCCqGSM49
AwEHoUQDQgAEzFSVTE5guxJRQ0VbZ8dicPs5e/DT7xpW7Yc9hq0VOchv7cbXuI/T
CwadDjGWX/oaz0ftFqrVmfkwZu+C58ioWg==
-----END EC PRIVATE KEY-----

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

1451
external/boringssl/ssl/test/runner/conn.go vendored Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,20 @@
// Copyright 2012 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// This code was translated into a form compatible with 6a from the public
// domain sources in SUPERCOP: http://bench.cr.yp.to/supercop.html
// +build amd64,!gccgo,!appengine
DATA ·REDMASK51(SB)/8, $0x0007FFFFFFFFFFFF
GLOBL ·REDMASK51(SB), 8, $8
DATA ·_121666_213(SB)/8, $996687872
GLOBL ·_121666_213(SB), 8, $8
DATA ·_2P0(SB)/8, $0xFFFFFFFFFFFDA
GLOBL ·_2P0(SB), 8, $8
DATA ·_2P1234(SB)/8, $0xFFFFFFFFFFFFE
GLOBL ·_2P1234(SB), 8, $8

View File

@@ -0,0 +1,88 @@
// Copyright 2012 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// This code was translated into a form compatible with 6a from the public
// domain sources in SUPERCOP: http://bench.cr.yp.to/supercop.html
// +build amd64,!gccgo,!appengine
// func cswap(inout *[5]uint64, v uint64)
TEXT ·cswap(SB),7,$0
MOVQ inout+0(FP),DI
MOVQ v+8(FP),SI
CMPQ SI,$1
MOVQ 0(DI),SI
MOVQ 80(DI),DX
MOVQ 8(DI),CX
MOVQ 88(DI),R8
MOVQ SI,R9
CMOVQEQ DX,SI
CMOVQEQ R9,DX
MOVQ CX,R9
CMOVQEQ R8,CX
CMOVQEQ R9,R8
MOVQ SI,0(DI)
MOVQ DX,80(DI)
MOVQ CX,8(DI)
MOVQ R8,88(DI)
MOVQ 16(DI),SI
MOVQ 96(DI),DX
MOVQ 24(DI),CX
MOVQ 104(DI),R8
MOVQ SI,R9
CMOVQEQ DX,SI
CMOVQEQ R9,DX
MOVQ CX,R9
CMOVQEQ R8,CX
CMOVQEQ R9,R8
MOVQ SI,16(DI)
MOVQ DX,96(DI)
MOVQ CX,24(DI)
MOVQ R8,104(DI)
MOVQ 32(DI),SI
MOVQ 112(DI),DX
MOVQ 40(DI),CX
MOVQ 120(DI),R8
MOVQ SI,R9
CMOVQEQ DX,SI
CMOVQEQ R9,DX
MOVQ CX,R9
CMOVQEQ R8,CX
CMOVQEQ R9,R8
MOVQ SI,32(DI)
MOVQ DX,112(DI)
MOVQ CX,40(DI)
MOVQ R8,120(DI)
MOVQ 48(DI),SI
MOVQ 128(DI),DX
MOVQ 56(DI),CX
MOVQ 136(DI),R8
MOVQ SI,R9
CMOVQEQ DX,SI
CMOVQEQ R9,DX
MOVQ CX,R9
CMOVQEQ R8,CX
CMOVQEQ R9,R8
MOVQ SI,48(DI)
MOVQ DX,128(DI)
MOVQ CX,56(DI)
MOVQ R8,136(DI)
MOVQ 64(DI),SI
MOVQ 144(DI),DX
MOVQ 72(DI),CX
MOVQ 152(DI),R8
MOVQ SI,R9
CMOVQEQ DX,SI
CMOVQEQ R9,DX
MOVQ CX,R9
CMOVQEQ R8,CX
CMOVQEQ R9,R8
MOVQ SI,64(DI)
MOVQ DX,144(DI)
MOVQ CX,72(DI)
MOVQ R8,152(DI)
MOVQ DI,AX
MOVQ SI,DX
RET

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,29 @@
// Copyright 2012 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package curve25519
import (
"fmt"
"testing"
)
const expectedHex = "89161fde887b2b53de549af483940106ecc114d6982daa98256de23bdf77661a"
func TestBaseScalarMult(t *testing.T) {
var a, b [32]byte
in := &a
out := &b
a[0] = 1
for i := 0; i < 200; i++ {
ScalarBaseMult(out, in)
in, out = out, in
}
result := fmt.Sprintf("%x", in[:])
if result != expectedHex {
t.Errorf("incorrect result: got %s, want %s", result, expectedHex)
}
}

View File

@@ -0,0 +1,23 @@
// Copyright 2012 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Package curve25519 provides an implementation of scalar multiplication on
// the elliptic curve known as curve25519. See http://cr.yp.to/ecdh.html
package curve25519 // import "golang.org/x/crypto/curve25519"
// basePoint is the x coordinate of the generator of the curve.
var basePoint = [32]byte{9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
// ScalarMult sets dst to the product in*base where dst and base are the x
// coordinates of group points and all values are in little-endian form.
func ScalarMult(dst, in, base *[32]byte) {
scalarMult(dst, in, base)
}
// ScalarBaseMult sets dst to the product in*base where dst and base are the x
// coordinates of group points, base is the standard generator and all values
// are in little-endian form.
func ScalarBaseMult(dst, in *[32]byte) {
ScalarMult(dst, in, &basePoint)
}

Some files were not shown because too many files have changed in this diff Show More