Move, modify and add key generation functions to project.
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
This commit is contained in:
parent
388e652315
commit
56362ebd68
|
@ -33,6 +33,8 @@
|
|||
4A61D83520D98D25006C7A76 /* NetworkExtension.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4A61D83420D98D25006C7A76 /* NetworkExtension.framework */; };
|
||||
4A8AABD820B6A79100B6D8C1 /* UITableView+WireGuard.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4A8AABD720B6A79100B6D8C1 /* UITableView+WireGuard.swift */; };
|
||||
4AADEA2B212616F7008C24FD /* String+Arrays.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5FA1D50F2124D80C00DBA2E6 /* String+Arrays.swift */; };
|
||||
4ABFFEA0212D39A000107136 /* x25519.c in Sources */ = {isa = PBXBuildFile; fileRef = 4ABFFE9F212D39A000107136 /* x25519.c */; };
|
||||
4ABFFEA3212D3C8300107136 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4ABFFEA2212D3C8300107136 /* Security.framework */; };
|
||||
4AC086832120B9F900CEE5ED /* ProviderConfigurationKeys.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4AC086822120B9F900CEE5ED /* ProviderConfigurationKeys.swift */; };
|
||||
4AC086852120BCB500CEE5ED /* ProviderConfigurationKeys.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4AC086822120B9F900CEE5ED /* ProviderConfigurationKeys.swift */; };
|
||||
4AC086862120BD5800CEE5ED /* PacketTunnelProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4A61D82820D98CE2006C7A76 /* PacketTunnelProvider.swift */; };
|
||||
|
@ -115,6 +117,10 @@
|
|||
4A61D83320D98D07006C7A76 /* WireGuard.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = WireGuard.entitlements; sourceTree = "<group>"; };
|
||||
4A61D83420D98D25006C7A76 /* NetworkExtension.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = NetworkExtension.framework; path = System/Library/Frameworks/NetworkExtension.framework; sourceTree = SDKROOT; };
|
||||
4A8AABD720B6A79100B6D8C1 /* UITableView+WireGuard.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UITableView+WireGuard.swift"; sourceTree = "<group>"; };
|
||||
4ABFFE9D212D399F00107136 /* WireGuard-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "WireGuard-Bridging-Header.h"; sourceTree = "<group>"; };
|
||||
4ABFFE9E212D39A000107136 /* x25519.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = x25519.h; sourceTree = "<group>"; };
|
||||
4ABFFE9F212D39A000107136 /* x25519.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = x25519.c; sourceTree = "<group>"; };
|
||||
4ABFFEA2212D3C8300107136 /* Security.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Security.framework; path = System/Library/Frameworks/Security.framework; sourceTree = SDKROOT; };
|
||||
4AC086822120B9F900CEE5ED /* ProviderConfigurationKeys.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProviderConfigurationKeys.swift; sourceTree = "<group>"; };
|
||||
4AC5462D2116306F00749D21 /* Tunnel+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Tunnel+Extension.swift"; sourceTree = "<group>"; };
|
||||
4AD0900120DC4171000E9CF5 /* libwg-go.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = "libwg-go.a"; sourceTree = "<group>"; };
|
||||
|
@ -138,6 +144,7 @@
|
|||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
4ABFFEA3212D3C8300107136 /* Security.framework in Frameworks */,
|
||||
48CF751B34E9703133F1B1AF /* Pods_WireGuard.framework in Frameworks */,
|
||||
4A61D83520D98D25006C7A76 /* NetworkExtension.framework in Frameworks */,
|
||||
);
|
||||
|
@ -190,6 +197,7 @@
|
|||
4A4BACE420B5F1BF00F12B28 /* WireGuard */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
4ABFFEA1212D39CA00107136 /* Crypto */,
|
||||
4A61D83320D98D07006C7A76 /* WireGuard.entitlements */,
|
||||
4A4BAD1420B5F8C000F12B28 /* Models */,
|
||||
4A4BAD1120B5F7A000F12B28 /* ViewControllers */,
|
||||
|
@ -200,6 +208,7 @@
|
|||
4A4BACEC20B5F1C100F12B28 /* Assets.xcassets */,
|
||||
4A4BACEE20B5F1C100F12B28 /* LaunchScreen.storyboard */,
|
||||
4A4BACF120B5F1C100F12B28 /* Info.plist */,
|
||||
4ABFFE9D212D399F00107136 /* WireGuard-Bridging-Header.h */,
|
||||
4AEAC32A20F14BA9007B67AB /* Log.swift */,
|
||||
);
|
||||
path = WireGuard;
|
||||
|
@ -276,6 +285,15 @@
|
|||
path = WireGuardNetworkExtension;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
4ABFFEA1212D39CA00107136 /* Crypto */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
4ABFFE9F212D39A000107136 /* x25519.c */,
|
||||
4ABFFE9E212D39A000107136 /* x25519.h */,
|
||||
);
|
||||
path = Crypto;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
4AC086812120B9E600CEE5ED /* Shared */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
|
@ -315,6 +333,7 @@
|
|||
A447093459F091F4358E843F /* Frameworks */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
4ABFFEA2212D3C8300107136 /* Security.framework */,
|
||||
4A61D83420D98D25006C7A76 /* NetworkExtension.framework */,
|
||||
861983CAE8FDC13BC83E7E04 /* Pods_WireGuard.framework */,
|
||||
);
|
||||
|
@ -566,6 +585,7 @@
|
|||
4AC5462E2116306F00749D21 /* Tunnel+Extension.swift in Sources */,
|
||||
5FCC4343212B3092009A9C58 /* QRScanViewController.swift in Sources */,
|
||||
4A4BAD0E20B5F6C300F12B28 /* Coordinator.swift in Sources */,
|
||||
4ABFFEA0212D39A000107136 /* x25519.c in Sources */,
|
||||
4A4BA6D820B73CBA00223AB8 /* TunnelConfigurationTableViewController.swift in Sources */,
|
||||
4A4BAD2020B6026900F12B28 /* Peer+CoreDataProperties.swift in Sources */,
|
||||
5FA1D4CD2124A05C00DBA2E6 /* Interface+Extension.swift in Sources */,
|
||||
|
@ -755,6 +775,7 @@
|
|||
buildSettings = {
|
||||
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CODE_SIGN_ENTITLEMENTS = WireGuard/WireGuard.entitlements;
|
||||
CODE_SIGN_STYLE = Manual;
|
||||
DEVELOPMENT_TEAM = 67JZJ7TWU3;
|
||||
|
@ -767,6 +788,8 @@
|
|||
PRODUCT_BUNDLE_IDENTIFIER = com.wireguard.ios.WireGuard;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||
SWIFT_OBJC_BRIDGING_HEADER = "WireGuard/WireGuard-Bridging-Header.h";
|
||||
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
||||
SWIFT_VERSION = 4.0;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
};
|
||||
|
@ -778,6 +801,7 @@
|
|||
buildSettings = {
|
||||
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CODE_SIGN_ENTITLEMENTS = WireGuard/WireGuard.entitlements;
|
||||
CODE_SIGN_STYLE = Manual;
|
||||
DEVELOPMENT_TEAM = "";
|
||||
|
@ -790,6 +814,7 @@
|
|||
PRODUCT_BUNDLE_IDENTIFIER = com.wireguard.ios.WireGuard;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||
SWIFT_OBJC_BRIDGING_HEADER = "WireGuard/WireGuard-Bridging-Header.h";
|
||||
SWIFT_VERSION = 4.0;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
};
|
||||
|
|
|
@ -171,6 +171,9 @@
|
|||
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="C1M-bh-5mf">
|
||||
<rect key="frame" x="240" y="0.0" width="103" height="35.5"/>
|
||||
<state key="normal" title="Generate"/>
|
||||
<connections>
|
||||
<action selector="generateTapped:" destination="06N-KU-LSv" eventType="touchUpInside" id="efE-zK-eCe"/>
|
||||
</connections>
|
||||
</button>
|
||||
</subviews>
|
||||
</stackView>
|
||||
|
|
|
@ -0,0 +1,177 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0+
|
||||
*
|
||||
* Copyright (C) 2015-2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
|
||||
*
|
||||
* Curve25519 ECDH functions, based on TweetNaCl but cleaned up.
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <CommonCrypto/CommonRandom.h>
|
||||
|
||||
#include "x25519.h"
|
||||
|
||||
typedef int64_t fe[16];
|
||||
|
||||
static inline void carry(fe o)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 16; ++i) {
|
||||
o[(i + 1) % 16] += (i == 15 ? 38 : 1) * (o[i] >> 16);
|
||||
o[i] &= 0xffff;
|
||||
}
|
||||
}
|
||||
|
||||
static inline void cswap(fe p, fe q, int b)
|
||||
{
|
||||
int i;
|
||||
int64_t t, c = ~(b - 1);
|
||||
|
||||
for (i = 0; i < 16; ++i) {
|
||||
t = c & (p[i] ^ q[i]);
|
||||
p[i] ^= t;
|
||||
q[i] ^= t;
|
||||
}
|
||||
}
|
||||
|
||||
static inline void pack(uint8_t *o, const fe n)
|
||||
{
|
||||
int i, j, b;
|
||||
fe m, t;
|
||||
|
||||
memcpy(t, n, sizeof(t));
|
||||
carry(t);
|
||||
carry(t);
|
||||
carry(t);
|
||||
for (j = 0; j < 2; ++j) {
|
||||
m[0] = t[0] - 0xffed;
|
||||
for (i = 1; i < 15; ++i) {
|
||||
m[i] = t[i] - 0xffff - ((m[i - 1] >> 16) & 1);
|
||||
m[i - 1] &= 0xffff;
|
||||
}
|
||||
m[15] = t[15] - 0x7fff - ((m[14] >> 16) & 1);
|
||||
b = (m[15] >> 16) & 1;
|
||||
m[14] &= 0xffff;
|
||||
cswap(t, m, 1 - b);
|
||||
}
|
||||
for (i = 0; i < 16; ++i) {
|
||||
o[2 * i] = t[i] & 0xff;
|
||||
o[2 * i + 1] = t[i] >> 8;
|
||||
}
|
||||
}
|
||||
|
||||
static inline void unpack(fe o, const uint8_t *n)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 16; ++i)
|
||||
o[i] = n[2 * i] + ((int64_t)n[2 * i + 1] << 8);
|
||||
o[15] &= 0x7fff;
|
||||
}
|
||||
|
||||
static inline void add(fe o, const fe a, const fe b)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 16; ++i)
|
||||
o[i] = a[i] + b[i];
|
||||
}
|
||||
|
||||
static inline void subtract(fe o, const fe a, const fe b)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 16; ++i)
|
||||
o[i] = a[i] - b[i];
|
||||
}
|
||||
|
||||
static inline void multmod(fe o, const fe a, const fe b)
|
||||
{
|
||||
int i, j;
|
||||
int64_t t[31] = { 0 };
|
||||
|
||||
for (i = 0; i < 16; ++i) {
|
||||
for (j = 0; j < 16; ++j)
|
||||
t[i + j] += a[i] * b[j];
|
||||
}
|
||||
for (i = 0; i < 15; ++i)
|
||||
t[i] += 38 * t[i + 16];
|
||||
memcpy(o, t, sizeof(fe));
|
||||
carry(o);
|
||||
carry(o);
|
||||
}
|
||||
|
||||
static inline void invert(fe o, const fe i)
|
||||
{
|
||||
fe c;
|
||||
int a;
|
||||
|
||||
memcpy(c, i, sizeof(c));
|
||||
for (a = 253; a >= 0; --a) {
|
||||
multmod(c, c, c);
|
||||
if (a != 2 && a != 4)
|
||||
multmod(c, c, i);
|
||||
}
|
||||
memcpy(o, c, sizeof(fe));
|
||||
}
|
||||
|
||||
static void curve25519_shared_secret(uint8_t shared_secret[32], const uint8_t private_key[32], const uint8_t public_key[32])
|
||||
{
|
||||
static const fe a24 = { 0xdb41, 1 };
|
||||
uint8_t z[32];
|
||||
int64_t r;
|
||||
int i;
|
||||
fe a = { 1 }, b, c = { 0 }, d = { 1 }, e, f, x;
|
||||
|
||||
memcpy(z, private_key, sizeof(z));
|
||||
|
||||
z[31] = (z[31] & 127) | 64;
|
||||
z[0] &= 248;
|
||||
|
||||
unpack(x, public_key);
|
||||
memcpy(b, x, sizeof(b));
|
||||
|
||||
for (i = 254; i >= 0; --i) {
|
||||
r = (z[i >> 3] >> (i & 7)) & 1;
|
||||
cswap(a, b, r);
|
||||
cswap(c, d, r);
|
||||
add(e, a, c);
|
||||
subtract(a, a, c);
|
||||
add(c, b, d);
|
||||
subtract(b, b, d);
|
||||
multmod(d, e, e);
|
||||
multmod(f, a, a);
|
||||
multmod(a, c, a);
|
||||
multmod(c, b, e);
|
||||
add(e, a, c);
|
||||
subtract(a, a, c);
|
||||
multmod(b, a, a);
|
||||
subtract(c, d, f);
|
||||
multmod(a, c, a24);
|
||||
add(a, a, d);
|
||||
multmod(c, c, a);
|
||||
multmod(a, d, f);
|
||||
multmod(d, b, x);
|
||||
multmod(b, e, e);
|
||||
cswap(a, b, r);
|
||||
cswap(c, d, r);
|
||||
}
|
||||
invert(c, c);
|
||||
multmod(a, a, c);
|
||||
pack(shared_secret, a);
|
||||
}
|
||||
|
||||
void curve25519_derive_public_key(uint8_t public_key[32], const uint8_t private_key[32])
|
||||
{
|
||||
static const uint8_t basepoint[32] = { 9 };
|
||||
|
||||
curve25519_shared_secret(public_key, private_key, basepoint);
|
||||
}
|
||||
|
||||
void curve25519_generate_private_key(uint8_t private_key[32])
|
||||
{
|
||||
CCRandomGenerateBytes(private_key, 32);
|
||||
private_key[31] = (private_key[31] & 127) | 64;
|
||||
private_key[0] &= 248;
|
||||
}
|
|
@ -79,6 +79,7 @@ class TunnelConfigurationTableViewController: UITableViewController {
|
|||
case 0:
|
||||
let cell = tableView.dequeueReusableCell(type: InterfaceTableViewCell.self, for: indexPath)
|
||||
cell.model = tunnel.interface
|
||||
cell.delegate = self
|
||||
return cell
|
||||
case 1:
|
||||
let cell = tableView.dequeueReusableCell(type: PeerTableViewCell.self, for: indexPath)
|
||||
|
@ -141,6 +142,38 @@ extension TunnelConfigurationTableViewController: PeerTableViewCellDelegate {
|
|||
}
|
||||
}
|
||||
|
||||
extension TunnelConfigurationTableViewController: InterfaceTableViewCellDelegate {
|
||||
func generateKeys() {
|
||||
if let moc = tunnel.managedObjectContext {
|
||||
moc.perform {
|
||||
var privateKey = Data(count: 32)
|
||||
privateKey.withUnsafeMutableBytes { (mutableBytes) -> Void in
|
||||
curve25519_generate_private_key(mutableBytes)
|
||||
}
|
||||
|
||||
self.tunnel.interface?.privateKey = privateKey.base64EncodedString()
|
||||
|
||||
if let peers = self.tunnel.peers?.array as? [Peer] {
|
||||
peers.forEach {
|
||||
var publicKey = Data(count: 32)
|
||||
privateKey.withUnsafeBytes({ (privateKeyBytes) -> Void in
|
||||
publicKey.withUnsafeMutableBytes({ (mutableBytes) -> Void in
|
||||
curve25519_derive_public_key(mutableBytes, privateKeyBytes)
|
||||
})
|
||||
})
|
||||
$0.publicKey = publicKey.base64EncodedString()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
self.tableView.reloadData()
|
||||
}
|
||||
}
|
||||
|
||||
protocol InterfaceTableViewCellDelegate: class {
|
||||
func generateKeys()
|
||||
}
|
||||
|
||||
class InterfaceTableViewCell: UITableViewCell {
|
||||
var model: Interface! {
|
||||
didSet {
|
||||
|
@ -153,16 +186,22 @@ class InterfaceTableViewCell: UITableViewCell {
|
|||
}
|
||||
}
|
||||
|
||||
weak var delegate: InterfaceTableViewCellDelegate?
|
||||
|
||||
@IBOutlet weak var nameField: UITextField!
|
||||
@IBOutlet weak var addressesField: UITextField!
|
||||
@IBOutlet weak var privateKeyField: UITextField!
|
||||
@IBOutlet weak var publicKeyField: UITextField!
|
||||
@IBOutlet weak var listenPortField: UITextField!
|
||||
@IBOutlet weak var dnsField: UITextField!
|
||||
@IBOutlet weak var mtuField: UITextField!
|
||||
|
||||
@IBAction func generateTapped(_ sender: Any) {
|
||||
delegate?.generateKeys()
|
||||
}
|
||||
}
|
||||
|
||||
extension InterfaceTableViewCell: UITextFieldDelegate {
|
||||
|
||||
@IBAction
|
||||
func textfieldDidChange(_ sender: UITextField) {
|
||||
let string = sender.text
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
//
|
||||
// Use this file to import your target's public headers that you would like to expose to Swift.
|
||||
//
|
||||
|
||||
#include "x25519.h"
|
177
x25519/x25519.c
177
x25519/x25519.c
|
@ -1,177 +0,0 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0+
|
||||
*
|
||||
* Copyright (C) 2015-2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
|
||||
*
|
||||
* Curve25519 ECDH functions, based on TweetNaCl but cleaned up.
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <sys/random.h>
|
||||
|
||||
#include "x25519.h"
|
||||
|
||||
typedef int64_t fe[16];
|
||||
|
||||
static inline void carry(fe o)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 16; ++i) {
|
||||
o[(i + 1) % 16] += (i == 15 ? 38 : 1) * (o[i] >> 16);
|
||||
o[i] &= 0xffff;
|
||||
}
|
||||
}
|
||||
|
||||
static inline void cswap(fe p, fe q, int b)
|
||||
{
|
||||
int i;
|
||||
int64_t t, c = ~(b - 1);
|
||||
|
||||
for (i = 0; i < 16; ++i) {
|
||||
t = c & (p[i] ^ q[i]);
|
||||
p[i] ^= t;
|
||||
q[i] ^= t;
|
||||
}
|
||||
}
|
||||
|
||||
static inline void pack(uint8_t *o, const fe n)
|
||||
{
|
||||
int i, j, b;
|
||||
fe m, t;
|
||||
|
||||
memcpy(t, n, sizeof(t));
|
||||
carry(t);
|
||||
carry(t);
|
||||
carry(t);
|
||||
for (j = 0; j < 2; ++j) {
|
||||
m[0] = t[0] - 0xffed;
|
||||
for (i = 1; i < 15; ++i) {
|
||||
m[i] = t[i] - 0xffff - ((m[i - 1] >> 16) & 1);
|
||||
m[i - 1] &= 0xffff;
|
||||
}
|
||||
m[15] = t[15] - 0x7fff - ((m[14] >> 16) & 1);
|
||||
b = (m[15] >> 16) & 1;
|
||||
m[14] &= 0xffff;
|
||||
cswap(t, m, 1 - b);
|
||||
}
|
||||
for (i = 0; i < 16; ++i) {
|
||||
o[2 * i] = t[i] & 0xff;
|
||||
o[2 * i + 1] = t[i] >> 8;
|
||||
}
|
||||
}
|
||||
|
||||
static inline void unpack(fe o, const uint8_t *n)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 16; ++i)
|
||||
o[i] = n[2 * i] + ((int64_t)n[2 * i + 1] << 8);
|
||||
o[15] &= 0x7fff;
|
||||
}
|
||||
|
||||
static inline void add(fe o, const fe a, const fe b)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 16; ++i)
|
||||
o[i] = a[i] + b[i];
|
||||
}
|
||||
|
||||
static inline void subtract(fe o, const fe a, const fe b)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 16; ++i)
|
||||
o[i] = a[i] - b[i];
|
||||
}
|
||||
|
||||
static inline void multmod(fe o, const fe a, const fe b)
|
||||
{
|
||||
int i, j;
|
||||
int64_t t[31] = { 0 };
|
||||
|
||||
for (i = 0; i < 16; ++i) {
|
||||
for (j = 0; j < 16; ++j)
|
||||
t[i + j] += a[i] * b[j];
|
||||
}
|
||||
for (i = 0; i < 15; ++i)
|
||||
t[i] += 38 * t[i + 16];
|
||||
memcpy(o, t, sizeof(fe));
|
||||
carry(o);
|
||||
carry(o);
|
||||
}
|
||||
|
||||
static inline void invert(fe o, const fe i)
|
||||
{
|
||||
fe c;
|
||||
int a;
|
||||
|
||||
memcpy(c, i, sizeof(c));
|
||||
for (a = 253; a >= 0; --a) {
|
||||
multmod(c, c, c);
|
||||
if (a != 2 && a != 4)
|
||||
multmod(c, c, i);
|
||||
}
|
||||
memcpy(o, c, sizeof(fe));
|
||||
}
|
||||
|
||||
static void curve25519_shared_secret(uint8_t shared_secret[32], const uint8_t private_key[32], const uint8_t public_key[32])
|
||||
{
|
||||
static const fe a24 = { 0xdb41, 1 };
|
||||
uint8_t z[32];
|
||||
int64_t r;
|
||||
int i;
|
||||
fe a = { 1 }, b, c = { 0 }, d = { 1 }, e, f, x;
|
||||
|
||||
memcpy(z, private_key, sizeof(z));
|
||||
|
||||
z[31] = (z[31] & 127) | 64;
|
||||
z[0] &= 248;
|
||||
|
||||
unpack(x, public_key);
|
||||
memcpy(b, x, sizeof(b));
|
||||
|
||||
for (i = 254; i >= 0; --i) {
|
||||
r = (z[i >> 3] >> (i & 7)) & 1;
|
||||
cswap(a, b, r);
|
||||
cswap(c, d, r);
|
||||
add(e, a, c);
|
||||
subtract(a, a, c);
|
||||
add(c, b, d);
|
||||
subtract(b, b, d);
|
||||
multmod(d, e, e);
|
||||
multmod(f, a, a);
|
||||
multmod(a, c, a);
|
||||
multmod(c, b, e);
|
||||
add(e, a, c);
|
||||
subtract(a, a, c);
|
||||
multmod(b, a, a);
|
||||
subtract(c, d, f);
|
||||
multmod(a, c, a24);
|
||||
add(a, a, d);
|
||||
multmod(c, c, a);
|
||||
multmod(a, d, f);
|
||||
multmod(d, b, x);
|
||||
multmod(b, e, e);
|
||||
cswap(a, b, r);
|
||||
cswap(c, d, r);
|
||||
}
|
||||
invert(c, c);
|
||||
multmod(a, a, c);
|
||||
pack(shared_secret, a);
|
||||
}
|
||||
|
||||
void curve25519_derive_public_key(uint8_t public_key[32], const uint8_t private_key[32])
|
||||
{
|
||||
static const uint8_t basepoint[32] = { 9 };
|
||||
|
||||
curve25519_shared_secret(public_key, private_key, basepoint);
|
||||
}
|
||||
|
||||
void curve25519_generate_private_key(uint8_t private_key[32])
|
||||
{
|
||||
getentropy(private_key, 32);
|
||||
private_key[31] = (private_key[31] & 127) | 64;
|
||||
private_key[0] &= 248;
|
||||
}
|
Loading…
Reference in New Issue