Compare commits
15 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5152bb6e5e | ||
| 9285f8e583 | |||
| c5ec067a79 | |||
| 387f5d4725 | |||
| c4d73026b5 | |||
| 516c4f2f80 | |||
|
|
6ff47cec92 | ||
|
|
5b1fa185f7 | ||
|
|
d941638779 | ||
|
|
e6bef22494 | ||
|
|
3edc477069 | ||
|
|
5b618c08ed | ||
|
|
69514943a9 | ||
|
|
955090b079 | ||
|
|
6191b29e49 |
Binary file not shown.
|
After Width: | Height: | Size: 18 KiB |
@@ -1,7 +1,7 @@
|
||||
# Superball
|
||||

|
||||
|
||||
Superball provides Tor-like location privacy for Nostr users. A **Superball** is a wrapped nostr event, similar to a TOR onion packet, that bounces between nostr relays and **Throwers**.
|
||||
Superball provides remailer-like location privacy for Nostr users. A **Superball** is a wrapped nostr event, similar to a TOR onion packet, that bounces between nostr relays and **Throwers**.
|
||||
|
||||
A **Thrower** is a nostr-capable daemon that monitors nostr nodes, looks for superballs posted for them, grabs them, cryptographically unwraps them, rewraps them potentially with padding, then throws the superball to relay(s) that it is instructed to, when it is instructed to.
|
||||
|
||||
|
||||
@@ -131,13 +131,10 @@ I am a Thrower - an anonymizing node that provides location privacy for Nostr us
|
||||
1. **Never log sensitive data** - Don't store decrypted content or routing info
|
||||
2. **Generate new keys** - Use fresh ephemeral keys for each forward
|
||||
3. **Validate everything** - Check signatures, event structure, relay URLs
|
||||
4. **Rate limiting** - Don't process more than X events per minute from same source
|
||||
|
||||
### Privacy Rules
|
||||
1. **No correlation** - Don't link input events to output events in logs
|
||||
2. **Clear memory** - Immediately clear decrypted data after processing
|
||||
3. **Random timing** - Add jitter to specified delays
|
||||
4. **Mix traffic** - Send decoy traffic when idle (optional)
|
||||
|
||||
### Processing Rules
|
||||
1. **First come, first served** - Process events in order received
|
||||
|
||||
49
Trash/trash.json
Normal file
49
Trash/trash.json
Normal file
@@ -0,0 +1,49 @@
|
||||
Reply to a post from Primal
|
||||
|
||||
{
|
||||
"kind": 1,
|
||||
"created_at": 1763420960,
|
||||
"content": "From Primal.",
|
||||
"pubkey": "8ff74724ed641b3c28e5a86d7c5cbc49c37638ace8c6c38935860e7a5eedde0e",
|
||||
"id": "555c77e419c6f34d1d36b6baf36489c5eb17d829645c940fc996d90c26df59a1",
|
||||
"tags": [
|
||||
[
|
||||
"e",
|
||||
"ac50dd87901863590d577fb9080ab294b8dd1b6b10563e9733d5bad817c735db",
|
||||
"wss://nos.lol",
|
||||
"root"
|
||||
],
|
||||
[
|
||||
"p",
|
||||
"8ff74724ed641b3c28e5a86d7c5cbc49c37638ace8c6c38935860e7a5eedde0e"
|
||||
],
|
||||
[
|
||||
"r",
|
||||
"wss://nostr.mom/"
|
||||
],
|
||||
[
|
||||
"r",
|
||||
"wss://relay.laantungir.net/"
|
||||
]
|
||||
],
|
||||
"sig": "5ab8f7b43e972e2089ebc95f68c49cace183832a3f867801a85c689ce6797eaa52a60ba07847212019fc2361ffca276c74f9cd69402095c6c783faac2c827bde"
|
||||
}
|
||||
|
||||
|
||||
Reply to post from proposed superball builder change.
|
||||
|
||||
{
|
||||
"id": "56e6dadc32afe11f13e83fcf8107ea8a819e4a96232d64eacafd10370224e685",
|
||||
"sig": "3766102783acfc7654f134b1dc5fd716e89e154fc81a96c7f60d20a867e5b52919cdfa7a01151550880e4e8a2945ef05feb43c022bbd7761724ded8308254b1d",
|
||||
"kind": 1,
|
||||
"tags": [
|
||||
[
|
||||
"e",
|
||||
"ac50dd87901863590d577fb9080ab294b8dd1b6b10563e9733d5bad817c735db",
|
||||
"root"
|
||||
]
|
||||
],
|
||||
"pubkey": "8ff74724ed641b3c28e5a86d7c5cbc49c37638ace8c6c38935860e7a5eedde0e",
|
||||
"content": "Yeah, it is a great night.",
|
||||
"created_at": 1763420892
|
||||
}
|
||||
BIN
assets/20250926_100936_sb1.png
Normal file
BIN
assets/20250926_100936_sb1.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 82 KiB |
@@ -1,3 +1,3 @@
|
||||
#!/bin/bash
|
||||
|
||||
rsync -avz --chmod=644 --progress web/{superball.html,thrower.html,superball-shared.css} ubuntu@laantungir.net:WWW/superball/
|
||||
rsync -avz --chmod=D755,F644 --progress web/ ubuntu@laantungir.net:WWW/superball/
|
||||
|
||||
80
nostr_post.md
Normal file
80
nostr_post.md
Normal file
@@ -0,0 +1,80 @@
|
||||
# Superball: Anonymous Nostr Posting
|
||||
|
||||
|
||||

|
||||
|
||||
This is an experiment I call #Superball.
|
||||
|
||||
Superballs are a way to post nostr events that help preserve the anonymity and location of the sender. Superballs use timing delays and add or subtract event padding to help defeat timing and size analysis, such as is used to help defeat TOR anonymity.
|
||||
|
||||
A Superball is a wrapped nostr event that is posted to a relay and picked up by a "Thrower". A Thrower is a program that watches relays for Superballs that are marked for them. The Thrower grabs the Superball, decrypts the outer shell of the Superball and reads the instructions inside, which tell the Thrower:
|
||||
|
||||
1. What relays to throw the superball to next.
|
||||
2. How long to wait before throwing the superball.
|
||||
3. Whether to add or remove padding to the superball to obscure its size.
|
||||
|
||||
When you create a Superball, you can chain throwers together. Depending on where the Thrower is in the chain, the Thrower will either rewrap the Superball with optional padding and post it to relays where it can be picked up by the next Thrower, or post the final event.
|
||||
|
||||
But enough talk. It's best understood by using it.
|
||||
|
||||
I have implemented the protocol in two web pages, which you can use to test it out:
|
||||
|
||||
This page lets you create and throw a superball. You can log in as yourself if you want, and just throw a superball. There are already throwers up. [https://laantungir.net/superball/superball.html](https://laantungir.net/superball/superball.html)
|
||||
|
||||
|
||||
This page lets you create a thrower. You can open as many of these pages as you want to create as many throwers as you want. You can watch your superballs propogate through your throwers. Don't log in as yourself. Log in as a new account to create a thrower. [https://laantungir.net/superball/thrower.html](https://laantungir.net/superball/thrower.html)
|
||||
|
||||
If you don't like reading instructions, go ahead and dive in. You can probably figure it out if you are nostr savy.
|
||||
|
||||
|
||||
If you like instructions, keep reading:
|
||||
|
||||
## QUICK START ONE- Throw a single bounce Superball
|
||||
|
||||
Go here to create a superball and throw it:
|
||||
|
||||
[https://laantungir.net/superball/superball.html](https://laantungir.net/superball/superball.html)
|
||||
|
||||
1. Sign in with your favorite nostr method, or create a new throwaway test key.
|
||||

|
||||
|
||||
2. Create a type 1 event that will eventually be posted.
|
||||

|
||||
|
||||
3. Click on the Add Bounce button.
|
||||

|
||||
4. You have to, at a minimum, choose a thrower, along with what relays you want the thrower to throw your event to. The default delay is 30 seconds.
|
||||
5. Click on Throw Superball, with the blue outline.
|
||||
6. Scroll down to Event Flow Visualization. This will show you how your Superball will bounce around NOSTR.
|
||||

|
||||
7. Click on Throw Superball.
|
||||
8. Click on Reset Builder to start again.
|
||||
|
||||
## Quick Start Two: Throw a Double Bounce Superball
|
||||
|
||||
1. Click on Reset Builder on the bottom right of the page.
|
||||
2. Repeat steps 1-6
|
||||
3. Click on Add Bounce, and add another bounce. Note that with 2 or more bounces, you can now specify that the thrower add padding to the Superball, to defeat any size analysis of your superball.
|
||||
|
||||
## Quick Start Three: Create and Use Your Own Thrower
|
||||
|
||||
1. In a separate browser window, go to [https://laantungir.net/superball/thrower.html](https://laantungir.net/superball/thrower.html)
|
||||
2. Log in not with your own key, but with a key you want to use for your Thrower that you are going to create. Jot down the key.
|
||||

|
||||
3. Click on Edit Thrower Info, and give your thrower a fun name and description. Save the info. You may have to log back in for that information to display properly on this page.
|
||||
4. Go to Edit Relays to add relays that you want your Thrower to be able to read from and write to. Save Relay Configuration.
|
||||
5. Test Relays. Because your thrower will be publishing someone else's notes, it can't publish to relays that require authentication. That is what this button does.
|
||||
6. Click on Start Thrower. Your thrower will then publish a kind 12222 thrower information document. This lets the world know your thrower is alive and active.
|
||||
7. Go back to [https://laantungir.net/superball/superball.html](https://laantungir.net/superball/superball.html). Under Available Throwers, click on Refresh List and your thrower should appear. The account you logged into on the Superball Builder page has to follow at least one relay that the Thrower publishes to, or you won't see it.
|
||||
8. Go ahead and create a superball, select your thrower, and throw it.
|
||||
9. When the Thrower receives the Superball, it will show it in the Event Queue. You can follow the Processing Log if you encounter problems.
|
||||
|
||||
## Project Link
|
||||
|
||||
[https://git.laantungir.net/laantungir/super_ball](https://git.laantungir.net/laantungir/super_ball)
|
||||
|
||||
## Inspiration
|
||||
|
||||
When I was a kid, I used to buy superballs from gumball machines, go into parking lots, and throw my superballs down as hard as I could onto the pavement. Hours of fun.
|
||||
|
||||
The early cypherpunks used Anonymous Remailers. I believe this may have been one of the most anonymous ways to message ever created. Tor and I2P are great, and can't be replaced, but their immediate nature means that they will always be vulnerable to timing attacks. Remailers helped solve this, and I think Superball can do the same on nostr.
|
||||
80
nostr_post.txt
Normal file
80
nostr_post.txt
Normal file
@@ -0,0 +1,80 @@
|
||||
Superball: Anonymous Nostr Posting
|
||||
|
||||
|
||||
https://laantungir.github.io/img_repo/0246a1c67289367573fcc552dffdc54867c15cca200572e12499db2d907df66b.jpg
|
||||
|
||||
This is an experiment I call #Superball.
|
||||
|
||||
Superballs are a way to post nostr events that help preserve the anonymity and location of the sender. Superballs use timing delays and add or subtract event padding to help defeat timing and size analysis, such as is used to help defeat TOR anonymity.
|
||||
|
||||
A Superball is a wrapped nostr event that is posted to a relay and picked up by a "Thrower". A Thrower is a program that watches relays for Superballs that are marked for them. The Thrower grabs the Superball, decrypts the outer shell of the Superball and reads the instructions inside, which tell the Thrower:
|
||||
|
||||
1. What relays to throw the superball to next.
|
||||
2. How long to wait before throwing the superball.
|
||||
3. Whether to add or remove padding to the superball to obscure its size.
|
||||
|
||||
When you create a Superball, you can chain throwers together. Depending on where the Thrower is in the chain, the Thrower will either rewrap the Superball with optional padding and post it to relays where it can be picked up by the next Thrower, or post the final event.
|
||||
|
||||
But enough talk. It's best understood by using it.
|
||||
|
||||
I have implemented the protocol in two web pages, which you can use to test it out:
|
||||
|
||||
This page lets you create and throw a superball. You can log in as yourself if you want, and just throw a superball. There are already throwers up. https://laantungir.net/superball/superball.html
|
||||
|
||||
|
||||
This page lets you create a thrower. You can open as many of these pages as you want to create as many throwers as you want. You can watch your superballs propogate through your throwers. Don't log in as yourself. Log in as a new account to create a thrower. https://laantungir.net/superball/thrower.html
|
||||
|
||||
If you don't like reading instructions, go ahead and dive in. You can probably figure it out if you are nostr savy.
|
||||
|
||||
|
||||
If you like instructions, keep reading:
|
||||
|
||||
QUICK START ONE- Throw a single bounce Superball
|
||||
|
||||
Go here to create a superball and throw it:
|
||||
|
||||
https://laantungir.net/superball/superball.html
|
||||
|
||||
1. Sign in with your favorite nostr method, or create a new throwaway test key.
|
||||
https://laantungir.net/superball/img/sb1.png
|
||||
|
||||
2. Create a type 1 event that will eventually be posted.
|
||||
https://laantungir.net/superball/img/sb2.png
|
||||
|
||||
3. Click on the Add Bounce button.
|
||||
https://laantungir.net/superball/img/sb3.png
|
||||
4. You have to, at a minimum, choose a thrower, along with what relays you want the thrower to throw your event to. The default delay is 30 seconds.
|
||||
5. Click on Throw Superball, with the blue outline.
|
||||
6. Scroll down to Event Flow Visualization. This will show you how your Superball will bounce around NOSTR.
|
||||
https://laantungir.net/superball/img/sb4.png
|
||||
7. Click on Throw Superball.
|
||||
8. Click on Reset Builder to start again.
|
||||
|
||||
Quick Start Two: Throw a Double Bounce Superball
|
||||
|
||||
1. Click on Reset Builder on the bottom right of the page.
|
||||
2. Repeat steps 1-6
|
||||
3. Click on Add Bounce, and add another bounce. Note that with 2 or more bounces, you can now specify that the thrower add padding to the Superball, to defeat any size analysis of your superball.
|
||||
|
||||
Quick Start Three: Create and Use Your Own Thrower
|
||||
|
||||
1. In a separate browser window, go to https://laantungir.net/superball/thrower.html
|
||||
2. Log in not with your own key, but with a key you want to use for your Thrower that you are going to create. Jot down the key.
|
||||
https://laantungir.net/superball/img/thrower01.png
|
||||
3. Click on Edit Thrower Info, and give your thrower a fun name and description. Save the info. You may have to log back in for that information to display properly on this page.
|
||||
4. Go to Edit Relays to add relays that you want your Thrower to be able to read from and write to. Save Relay Configuration.
|
||||
5. Test Relays. Because your thrower will be publishing someone else's notes, it can't publish to relays that require authentication. That is what this button does.
|
||||
6. Click on Start Thrower. Your thrower will then publish a kind 12222 thrower information document. This lets the world know your thrower is alive and active.
|
||||
7. Go back to https://laantungir.net/superball/superball.html. Under Available Throwers, click on Refresh List and your thrower should appear. The account you logged into on the Superball Builder page has to follow at least one relay that the Thrower publishes to, or you won't see it.
|
||||
8. Go ahead and create a superball, select your thrower, and throw it.
|
||||
9. When the Thrower receives the Superball, it will show it in the Event Queue. You can follow the Processing Log if you encounter problems.
|
||||
|
||||
Project Link
|
||||
|
||||
https://git.laantungir.net/laantungir/super_ball
|
||||
|
||||
Inspiration
|
||||
|
||||
When I was a kid, I used to buy superballs from gumball machines, go into parking lots, and throw my superballs down as hard as I could onto the pavement. Hours of fun.
|
||||
|
||||
The early cypherpunks used Anonymous Remailers. I believe this may have been one of the most anonymous ways to message ever created. Tor and I2P are great, and can't be replaced, but their immediate nature means that they will always be vulnerable to timing attacks. Remailers helped solve this, and I think Superball can do the same on nostr.
|
||||
283
thrower_daemon/README.md
Normal file
283
thrower_daemon/README.md
Normal file
@@ -0,0 +1,283 @@
|
||||
# Superball Thrower Daemon
|
||||
|
||||
A standalone Node.js daemon implementation of the Superball Thrower functionality, extracted from the web-based implementation. This daemon runs as a system service and provides privacy-focused routing for the Superball protocol.
|
||||
|
||||
## Features
|
||||
|
||||
- **Complete Superball Protocol Support**: Implements SUP-01 through SUP-06
|
||||
- **NIP-44 Encryption**: Secure event routing with NOSTR encryption standards
|
||||
- **NIP-65 Relay Management**: Automatic relay list publishing and management
|
||||
- **Event Queue Processing**: Delayed processing with routing instructions
|
||||
- **Relay Authentication Testing**: Automatic detection of read/write capabilities
|
||||
- **Thrower Information Publishing**: SUP-06 compliant thrower announcements
|
||||
- **Maximum Delay Validation**: Security feature to prevent excessive delays (default: 86460 seconds = 1 day + 60s)
|
||||
- **Systemd Integration**: Runs as a secure system service
|
||||
- **Comprehensive Logging**: Detailed operation logs for monitoring
|
||||
|
||||
## Quick Start
|
||||
|
||||
1. **Install the daemon:**
|
||||
```bash
|
||||
chmod +x install.sh
|
||||
./install.sh
|
||||
```
|
||||
|
||||
2. **Configure your thrower:**
|
||||
```bash
|
||||
sudo nano /etc/superball/config.json
|
||||
```
|
||||
|
||||
3. **Start the service:**
|
||||
```bash
|
||||
sudo systemctl enable superball-thrower
|
||||
sudo systemctl start superball-thrower
|
||||
```
|
||||
|
||||
4. **Monitor the service:**
|
||||
```bash
|
||||
sudo systemctl status superball-thrower
|
||||
sudo journalctl -u superball-thrower -f
|
||||
```
|
||||
|
||||
## Configuration
|
||||
|
||||
The daemon uses `/etc/superball/config.json` for configuration. Key settings include:
|
||||
|
||||
### Required Settings
|
||||
- `privateKey`: Your thrower's private key (hex format)
|
||||
- `relays`: Array of relay configurations with read/write permissions
|
||||
|
||||
### Optional Settings
|
||||
- `throwerInfo`: Thrower Information Document settings (SUP-06)
|
||||
- `maxDelay`: Maximum delay in seconds for routing instructions (default: 86460 = 1 day + 60s)
|
||||
- `refreshRate`: How often to republish thrower info in seconds (default: 300)
|
||||
|
||||
### Example Configuration
|
||||
```json
|
||||
{
|
||||
"thrower": {
|
||||
"privateKey": "your-private-key-in-hex",
|
||||
"name": "My Superball Thrower",
|
||||
"description": "A privacy-focused Superball routing node",
|
||||
"maxDelay": 86460,
|
||||
"refreshRate": 300
|
||||
},
|
||||
"relays": [
|
||||
{
|
||||
"url": "wss://relay.laantungir.net",
|
||||
"read": true,
|
||||
"write": true
|
||||
},
|
||||
{
|
||||
"url": "wss://relay.damus.io",
|
||||
"read": true,
|
||||
"write": false
|
||||
}
|
||||
],
|
||||
"daemon": {
|
||||
"logLevel": "info",
|
||||
"maxQueueSize": 1000,
|
||||
"autoStart": false
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Architecture
|
||||
|
||||
### Core Components
|
||||
|
||||
1. **Event Monitor**: Subscribes to kind 22222 events across configured relays
|
||||
2. **Decryption Engine**: Handles NIP-44 decryption of routing instructions
|
||||
3. **Queue Processor**: Manages delayed event processing
|
||||
4. **Relay Manager**: Tests and manages relay authentication capabilities
|
||||
5. **Publisher**: Handles event forwarding and final posting
|
||||
|
||||
### Protocol Implementation
|
||||
|
||||
- **SUP-01**: Basic routing protocol support
|
||||
- **SUP-02**: Event queuing and delayed processing
|
||||
- **SUP-03**: Padding layer handling for privacy
|
||||
- **SUP-04**: Relay authentication and capability detection
|
||||
- **SUP-05**: Event validation and security checks
|
||||
- **SUP-06**: Thrower Information Document publishing
|
||||
|
||||
### Security Features
|
||||
|
||||
- **Maximum Delay Validation**: Prevents excessive routing delays (default: 86460 seconds)
|
||||
- **Event Deduplication**: Prevents processing the same event multiple times
|
||||
- **Relay Authentication**: Only uses write-capable relays for publishing
|
||||
- **Private Key Security**: Configuration file secured with proper permissions
|
||||
|
||||
## File Structure
|
||||
|
||||
```
|
||||
thrower_daemon/
|
||||
├── daemon.js # Main daemon implementation
|
||||
├── package.json # Node.js dependencies
|
||||
├── config.json # Example configuration
|
||||
├── superball-thrower.service # Systemd service file
|
||||
├── install.sh # Installation script
|
||||
└── README.md # This documentation
|
||||
```
|
||||
|
||||
## Dependencies
|
||||
|
||||
- **Node.js 16+**: Runtime environment
|
||||
- **nostr-tools**: NOSTR protocol implementation
|
||||
- **ws**: WebSocket client for relay connections
|
||||
|
||||
## Installation Details
|
||||
|
||||
The installation script (`install.sh`) performs the following:
|
||||
|
||||
1. **System Requirements Check**: Verifies Node.js and npm installation
|
||||
2. **Dependency Installation**: Installs required Node.js packages
|
||||
3. **User Creation**: Creates a dedicated `superball` system user
|
||||
4. **Directory Setup**: Creates log and configuration directories
|
||||
5. **Service Installation**: Installs and configures systemd service
|
||||
6. **Permission Setup**: Secures files with appropriate permissions
|
||||
|
||||
## Service Management
|
||||
|
||||
### Start/Stop/Restart
|
||||
```bash
|
||||
sudo systemctl start superball-thrower
|
||||
sudo systemctl stop superball-thrower
|
||||
sudo systemctl restart superball-thrower
|
||||
```
|
||||
|
||||
### Enable/Disable Auto-start
|
||||
```bash
|
||||
sudo systemctl enable superball-thrower
|
||||
sudo systemctl disable superball-thrower
|
||||
```
|
||||
|
||||
### View Status and Logs
|
||||
```bash
|
||||
sudo systemctl status superball-thrower
|
||||
sudo journalctl -u superball-thrower -f
|
||||
sudo journalctl -u superball-thrower --since "1 hour ago"
|
||||
```
|
||||
|
||||
## Monitoring
|
||||
|
||||
### Log Files
|
||||
- **System Logs**: `journalctl -u superball-thrower`
|
||||
- **Application Logs**: `/var/log/superball/daemon.log`
|
||||
|
||||
### Key Metrics to Monitor
|
||||
- **Events Processed**: Number of routing events handled
|
||||
- **Queue Length**: Current number of queued events
|
||||
- **Relay Connections**: Number of active relay connections
|
||||
- **Authentication Status**: Relay read/write capabilities
|
||||
|
||||
### Health Checks
|
||||
The daemon logs important events including:
|
||||
- Startup and shutdown
|
||||
- Relay connection status
|
||||
- Event processing statistics
|
||||
- Error conditions and recovery
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Common Issues
|
||||
|
||||
1. **Service Won't Start**
|
||||
- Check configuration file syntax: `sudo journalctl -u superball-thrower`
|
||||
- Verify private key format (64-character hex string)
|
||||
- Ensure relay URLs are valid WebSocket endpoints
|
||||
|
||||
2. **No Events Being Processed**
|
||||
- Verify relay connections in logs
|
||||
- Check if thrower info is being published
|
||||
- Confirm private key corresponds to expected public key
|
||||
|
||||
3. **Permission Errors**
|
||||
- Ensure configuration file is owned by `superball` user
|
||||
- Check directory permissions: `/var/log/superball`, `/etc/superball`
|
||||
|
||||
4. **Relay Connection Issues**
|
||||
- Test relay URLs manually with WebSocket tools
|
||||
- Check firewall settings for outbound connections
|
||||
- Verify relay authentication requirements
|
||||
|
||||
### Debug Mode
|
||||
Enable verbose logging by editing the service file:
|
||||
```bash
|
||||
sudo systemctl edit superball-thrower
|
||||
```
|
||||
|
||||
Add:
|
||||
```ini
|
||||
[Service]
|
||||
Environment=DEBUG=1
|
||||
```
|
||||
|
||||
## Security Considerations
|
||||
|
||||
### Private Key Security
|
||||
- Store private keys securely in the configuration file
|
||||
- Use proper file permissions (600) for configuration
|
||||
- Consider using hardware security modules for production
|
||||
|
||||
### Network Security
|
||||
- Use TLS-enabled relay connections (wss://)
|
||||
- Monitor relay authentication requirements
|
||||
- Implement firewall rules for outbound connections
|
||||
|
||||
### System Security
|
||||
- Run daemon as dedicated non-privileged user
|
||||
- Use systemd security features (NoNewPrivileges, etc.)
|
||||
- Regular security updates for Node.js and dependencies
|
||||
|
||||
## Development
|
||||
|
||||
### Running in Development Mode
|
||||
```bash
|
||||
cd thrower_daemon
|
||||
npm install
|
||||
node daemon.js
|
||||
```
|
||||
|
||||
### Configuration for Development
|
||||
Copy `config.json` to a local file and modify as needed:
|
||||
```bash
|
||||
cp config.json config-dev.json
|
||||
# Edit config-dev.json with your settings
|
||||
node daemon.js config-dev.json
|
||||
```
|
||||
|
||||
## Maximum Delay Feature
|
||||
|
||||
The daemon implements a maximum delay security feature:
|
||||
|
||||
- **Default Maximum**: 86460 seconds (1 day + 60 seconds)
|
||||
- **Purpose**: Prevents attackers from creating routing instructions with excessive delays
|
||||
- **Validation**: All incoming routing instructions are validated against the configured maximum
|
||||
- **Configuration**: Set via `maxDelay` field in thrower configuration
|
||||
- **Publishing**: Maximum delay is published in Thrower Information Documents (SUP-06)
|
||||
|
||||
## Contributing
|
||||
|
||||
This daemon is part of the Superball project. For contributions:
|
||||
|
||||
1. Follow the existing code style and patterns
|
||||
2. Test thoroughly with multiple relay configurations
|
||||
3. Update documentation for any new features
|
||||
4. Ensure backward compatibility with existing configurations
|
||||
|
||||
## License
|
||||
|
||||
This project follows the same license as the main Superball project.
|
||||
|
||||
## Support
|
||||
|
||||
For support and questions:
|
||||
- Check the logs first: `sudo journalctl -u superball-thrower`
|
||||
- Review this documentation
|
||||
- Check the main Superball project documentation
|
||||
- Report issues with detailed logs and configuration (redact private keys)
|
||||
|
||||
---
|
||||
|
||||
**⚠️ Security Warning**: Always secure your private keys and never share them. The daemon handles sensitive cryptographic operations and should be deployed with appropriate security measures.
|
||||
45
thrower_daemon/config.example.json
Normal file
45
thrower_daemon/config.example.json
Normal file
@@ -0,0 +1,45 @@
|
||||
{
|
||||
"thrower": {
|
||||
"privateKey": null,
|
||||
"publicKey": null,
|
||||
"name": "My Superball Thrower",
|
||||
"description": "A privacy-focused Superball Thrower node providing secure NOSTR event routing",
|
||||
"banner": "",
|
||||
"icon": "",
|
||||
"adminPubkey": "",
|
||||
"contact": "",
|
||||
"supportedSups": "1,2,3,4,5,6",
|
||||
"software": "https://git.laantungir.net/laantungir/super_ball.git",
|
||||
"version": "1.0.0",
|
||||
"privacyPolicy": "",
|
||||
"termsOfService": "",
|
||||
"refreshRate": 300,
|
||||
"content": ""
|
||||
},
|
||||
"relays": [
|
||||
{
|
||||
"url": "wss://relay.laantungir.net",
|
||||
"type": "",
|
||||
"authStatus": "unknown",
|
||||
"lastTested": null
|
||||
},
|
||||
{
|
||||
"url": "wss://relay.damus.io",
|
||||
"type": "",
|
||||
"authStatus": "unknown",
|
||||
"lastTested": null
|
||||
},
|
||||
{
|
||||
"url": "wss://nos.lol",
|
||||
"type": "",
|
||||
"authStatus": "unknown",
|
||||
"lastTested": null
|
||||
}
|
||||
],
|
||||
"daemon": {
|
||||
"logLevel": "info",
|
||||
"maxQueueSize": 1000,
|
||||
"maxLogEntries": 1000,
|
||||
"autoStart": false
|
||||
}
|
||||
}
|
||||
140
thrower_daemon/config.json
Normal file
140
thrower_daemon/config.json
Normal file
@@ -0,0 +1,140 @@
|
||||
{
|
||||
"thrower": {
|
||||
"privateKey": "520753551b14d4998c89b71c7aece8f4121a7142f3b06dca058256499847b159",
|
||||
"publicKey": "7a05466be7a0774c059021292e4616d179aa19f040eead7876629fd112c9fe96",
|
||||
"name": "Dragon",
|
||||
"description": "I'm medieval",
|
||||
"banner": "",
|
||||
"icon": "",
|
||||
"adminPubkey": "",
|
||||
"contact": "",
|
||||
"supportedSups": "1,2,3,4,5,6",
|
||||
"software": "https://git.laantungir.net/laantungir/super_ball.git",
|
||||
"version": "1.0.0",
|
||||
"privacyPolicy": "",
|
||||
"termsOfService": "",
|
||||
"refreshRate": 300,
|
||||
"maxDelay": 86460,
|
||||
"content": ""
|
||||
},
|
||||
"relays": [
|
||||
{
|
||||
"url": "wss://relay.laantungir.net",
|
||||
"read": true,
|
||||
"write": true,
|
||||
"authStatus": "unknown",
|
||||
"lastTested": null
|
||||
},
|
||||
{
|
||||
"url": "wss://relay.damus.io",
|
||||
"read": true,
|
||||
"write": true,
|
||||
"authStatus": "unknown",
|
||||
"lastTested": null
|
||||
},
|
||||
{
|
||||
"url": "wss://nos.lol",
|
||||
"read": true,
|
||||
"write": true,
|
||||
"authStatus": "unknown",
|
||||
"lastTested": null
|
||||
},
|
||||
{
|
||||
"url": "wss://nostr.wine",
|
||||
"read": true,
|
||||
"write": true,
|
||||
"authStatus": "unknown",
|
||||
"lastTested": null
|
||||
},
|
||||
{
|
||||
"url": "wss://eden.nostr.land",
|
||||
"read": true,
|
||||
"write": true,
|
||||
"authStatus": "unknown",
|
||||
"lastTested": null
|
||||
},
|
||||
{
|
||||
"url": "wss://relay.snort.social",
|
||||
"read": true,
|
||||
"write": true,
|
||||
"authStatus": "unknown",
|
||||
"lastTested": null
|
||||
},
|
||||
{
|
||||
"url": "wss://relay.primal.net",
|
||||
"read": true,
|
||||
"write": true,
|
||||
"authStatus": "unknown",
|
||||
"lastTested": null
|
||||
},
|
||||
{
|
||||
"url": "wss://relay.nostr.band",
|
||||
"read": true,
|
||||
"write": true,
|
||||
"authStatus": "unknown",
|
||||
"lastTested": null
|
||||
},
|
||||
{
|
||||
"url": "wss://premium.primal.net",
|
||||
"read": true,
|
||||
"write": false,
|
||||
"authStatus": "unknown",
|
||||
"lastTested": null
|
||||
},
|
||||
{
|
||||
"url": "wss://nostr.oxtr.dev",
|
||||
"read": true,
|
||||
"write": true,
|
||||
"authStatus": "unknown",
|
||||
"lastTested": null
|
||||
},
|
||||
{
|
||||
"url": "wss://purplepag.es",
|
||||
"read": true,
|
||||
"write": false,
|
||||
"authStatus": "unknown",
|
||||
"lastTested": null
|
||||
},
|
||||
{
|
||||
"url": "wss://offchain.pub",
|
||||
"read": true,
|
||||
"write": true,
|
||||
"authStatus": "unknown",
|
||||
"lastTested": null
|
||||
},
|
||||
{
|
||||
"url": "wss://nostr-pub.wellorder.net",
|
||||
"read": true,
|
||||
"write": true,
|
||||
"authStatus": "unknown",
|
||||
"lastTested": null
|
||||
},
|
||||
{
|
||||
"url": "wss://nostr.land",
|
||||
"read": true,
|
||||
"write": false,
|
||||
"authStatus": "unknown",
|
||||
"lastTested": null
|
||||
},
|
||||
{
|
||||
"url": "wss://nostr.mom",
|
||||
"read": true,
|
||||
"write": false,
|
||||
"authStatus": "unknown",
|
||||
"lastTested": null
|
||||
},
|
||||
{
|
||||
"url": "wss://pyramid.fiatjaf.com",
|
||||
"read": true,
|
||||
"write": false,
|
||||
"authStatus": "unknown",
|
||||
"lastTested": null
|
||||
}
|
||||
],
|
||||
"daemon": {
|
||||
"logLevel": "info",
|
||||
"maxQueueSize": 1000,
|
||||
"maxLogEntries": 1000,
|
||||
"autoStart": false
|
||||
}
|
||||
}
|
||||
1188
thrower_daemon/daemon.js
Normal file
1188
thrower_daemon/daemon.js
Normal file
File diff suppressed because it is too large
Load Diff
265
thrower_daemon/install.sh
Executable file
265
thrower_daemon/install.sh
Executable file
@@ -0,0 +1,265 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Superball Thrower Daemon Installation Script
|
||||
# This script installs and configures the Superball Thrower daemon
|
||||
|
||||
set -e
|
||||
|
||||
echo "🏀 Superball Thrower Daemon Installation"
|
||||
echo "========================================"
|
||||
|
||||
# Check if running as root
|
||||
if [[ $EUID -eq 0 ]]; then
|
||||
echo "❌ This script should not be run as root for security reasons"
|
||||
echo " Please run as a regular user with sudo privileges"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Function to check if command exists
|
||||
command_exists() {
|
||||
command -v "$1" >/dev/null 2>&1
|
||||
}
|
||||
|
||||
# Check for required system dependencies
|
||||
echo "📋 Checking system dependencies..."
|
||||
|
||||
# Check for curl
|
||||
if ! command_exists curl; then
|
||||
echo "❌ curl is required but not installed"
|
||||
echo " Please install curl: sudo apt update && sudo apt install curl"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Check for systemctl (systemd)
|
||||
if ! command_exists systemctl; then
|
||||
echo "❌ systemd is required but not found"
|
||||
echo " This script requires a systemd-based system"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Install latest Node.js using nvm
|
||||
echo "🔧 Installing latest Node.js using nvm..."
|
||||
|
||||
# Download and install nvm
|
||||
if [ ! -d "$HOME/.nvm" ]; then
|
||||
echo " Downloading and installing nvm..."
|
||||
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.3/install.sh | bash
|
||||
fi
|
||||
|
||||
# Load nvm
|
||||
export NVM_DIR="$HOME/.nvm"
|
||||
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"
|
||||
[ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion"
|
||||
|
||||
# Install Node.js 22 (latest LTS)
|
||||
echo " Installing Node.js 22..."
|
||||
nvm install 22
|
||||
nvm use 22
|
||||
|
||||
# Verify installation
|
||||
NODE_VERSION=$(node --version)
|
||||
NPM_VERSION=$(npm --version)
|
||||
echo "✅ Node.js $NODE_VERSION installed"
|
||||
echo "✅ npm $NPM_VERSION installed"
|
||||
|
||||
# Copy Node.js binaries to system-wide location
|
||||
echo "📋 Installing Node.js binaries system-wide..."
|
||||
NODE_PATH=$(which node)
|
||||
NPM_PATH=$(which npm)
|
||||
|
||||
if [ -n "$NODE_PATH" ] && [ -x "$NODE_PATH" ]; then
|
||||
# Remove any existing symlinks first
|
||||
sudo rm -f /usr/local/bin/node
|
||||
sudo cp "$NODE_PATH" /usr/local/bin/node
|
||||
sudo chmod +x /usr/local/bin/node
|
||||
echo "✅ Node.js binary copied to /usr/local/bin/node"
|
||||
else
|
||||
echo "❌ Failed to find Node.js executable"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -n "$NPM_PATH" ] && [ -x "$NPM_PATH" ]; then
|
||||
# Remove any existing symlinks first
|
||||
sudo rm -f /usr/local/bin/npm
|
||||
sudo cp "$NPM_PATH" /usr/local/bin/npm
|
||||
sudo chmod +x /usr/local/bin/npm
|
||||
echo "✅ npm binary copied to /usr/local/bin/npm"
|
||||
else
|
||||
echo "❌ Failed to find npm executable"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Install npm dependencies
|
||||
echo "📦 Installing npm dependencies..."
|
||||
if ! npm install; then
|
||||
echo "❌ Failed to install npm dependencies"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "✅ Dependencies installed successfully"
|
||||
|
||||
# Interactive configuration
|
||||
echo ""
|
||||
echo "⚙️ Thrower Configuration"
|
||||
echo "========================"
|
||||
echo "Please provide the following information for your Superball Thrower:"
|
||||
echo ""
|
||||
|
||||
# Prompt for configuration values
|
||||
read -p "Enter your private key (hex format, leave empty to generate new): " PRIVATE_KEY
|
||||
read -p "Enter your public key (hex format, leave empty if generating new): " PUBLIC_KEY
|
||||
read -p "Enter thrower name (e.g., 'My Superball Thrower'): " THROWER_NAME
|
||||
read -p "Enter thrower description: " THROWER_DESCRIPTION
|
||||
read -p "Enter banner URL (optional, press enter to skip): " BANNER_URL
|
||||
read -p "Enter icon URL (optional, press enter to skip): " ICON_URL
|
||||
|
||||
# Generate keypair if not provided
|
||||
if [ -z "$PRIVATE_KEY" ] || [ -z "$PUBLIC_KEY" ]; then
|
||||
echo "🔑 Generating new keypair..."
|
||||
# We'll let the daemon generate the keypair on first run
|
||||
PRIVATE_KEY=""
|
||||
PUBLIC_KEY=""
|
||||
fi
|
||||
|
||||
# Update config.json with user input
|
||||
echo "📝 Updating configuration file..."
|
||||
|
||||
# Create a temporary config file with user values
|
||||
cat > config.json << EOF
|
||||
{
|
||||
"thrower": {
|
||||
"privateKey": "$PRIVATE_KEY",
|
||||
"publicKey": "$PUBLIC_KEY",
|
||||
"name": "$THROWER_NAME",
|
||||
"description": "$THROWER_DESCRIPTION",
|
||||
"banner": "$BANNER_URL",
|
||||
"icon": "$ICON_URL",
|
||||
"adminPubkey": "",
|
||||
"contact": "",
|
||||
"supportedSups": "1,2,3,4,5,6",
|
||||
"software": "https://git.laantungir.net/laantungir/super_ball.git",
|
||||
"version": "1.0.0",
|
||||
"privacyPolicy": "",
|
||||
"termsOfService": "",
|
||||
"refreshRate": 300,
|
||||
"maxDelay": 86460
|
||||
},
|
||||
"relays": [
|
||||
{ "url": "wss://relay.laantungir.net", "read": true, "write": true, "authStatus": "unknown" },
|
||||
{ "url": "wss://relay.damus.io", "read": true, "write": true, "authStatus": "unknown" },
|
||||
{ "url": "wss://nos.lol", "read": true, "write": true, "authStatus": "unknown" },
|
||||
{ "url": "wss://relay.snort.social", "read": true, "write": true, "authStatus": "unknown" },
|
||||
{ "url": "wss://relay.primal.net", "read": true, "write": true, "authStatus": "unknown" },
|
||||
{ "url": "wss://relay.nostr.band", "read": true, "write": true, "authStatus": "unknown" },
|
||||
{ "url": "wss://nostr.oxtr.dev", "read": true, "write": true, "authStatus": "unknown" },
|
||||
{ "url": "wss://offchain.pub", "read": true, "write": true, "authStatus": "unknown" },
|
||||
{ "url": "wss://nostr-pub.wellorder.net", "read": true, "write": true, "authStatus": "unknown" }
|
||||
],
|
||||
"daemon": {
|
||||
"logLevel": "info",
|
||||
"maxQueueSize": 1000,
|
||||
"maxLogEntries": 1000,
|
||||
"autoStart": false
|
||||
}
|
||||
}
|
||||
EOF
|
||||
|
||||
echo "✅ Configuration updated"
|
||||
|
||||
# Create system user for the daemon
|
||||
echo "👤 Creating system user..."
|
||||
DAEMON_USER="superball-thrower"
|
||||
|
||||
if id "$DAEMON_USER" &>/dev/null; then
|
||||
echo "✅ User $DAEMON_USER already exists"
|
||||
else
|
||||
echo " Creating user: $DAEMON_USER"
|
||||
sudo useradd --system --no-create-home --shell /bin/false "$DAEMON_USER"
|
||||
echo "✅ User $DAEMON_USER created"
|
||||
fi
|
||||
|
||||
# Create installation directory
|
||||
INSTALL_DIR="/opt/superball-thrower"
|
||||
echo "📁 Setting up installation directory: $INSTALL_DIR"
|
||||
|
||||
sudo mkdir -p "$INSTALL_DIR"
|
||||
sudo cp daemon.js "$INSTALL_DIR/"
|
||||
sudo cp package.json "$INSTALL_DIR/"
|
||||
sudo cp config.json "$INSTALL_DIR/"
|
||||
|
||||
# Copy node_modules if it exists
|
||||
if [ -d "node_modules" ]; then
|
||||
sudo cp -r node_modules "$INSTALL_DIR/"
|
||||
fi
|
||||
|
||||
# Set ownership and permissions
|
||||
sudo chown -R "$DAEMON_USER:$DAEMON_USER" "$INSTALL_DIR"
|
||||
sudo chmod 755 "$INSTALL_DIR"
|
||||
sudo chmod 644 "$INSTALL_DIR"/*.js "$INSTALL_DIR"/*.json
|
||||
sudo chmod -R 755 "$INSTALL_DIR/node_modules" 2>/dev/null || true
|
||||
|
||||
echo "✅ Files installed to $INSTALL_DIR"
|
||||
|
||||
# Create log directory
|
||||
LOG_DIR="/var/log/superball-thrower"
|
||||
echo "📝 Creating log directory: $LOG_DIR"
|
||||
|
||||
sudo mkdir -p "$LOG_DIR"
|
||||
sudo chown "$DAEMON_USER:$DAEMON_USER" "$LOG_DIR"
|
||||
sudo chmod 755 "$LOG_DIR"
|
||||
|
||||
echo "✅ Log directory created"
|
||||
|
||||
# Install systemd service
|
||||
echo "⚙️ Installing systemd service..."
|
||||
|
||||
sudo cp superball-thrower.service /etc/systemd/system/
|
||||
sudo systemctl daemon-reload
|
||||
sudo systemctl enable superball-thrower.service
|
||||
|
||||
echo "✅ Systemd service installed and enabled"
|
||||
|
||||
# Initialize daemon if no keypair was provided
|
||||
if [ -z "$PRIVATE_KEY" ]; then
|
||||
echo "🔑 Initializing daemon to generate keypair..."
|
||||
# Create a simple init script that generates keypair
|
||||
sudo -u "$DAEMON_USER" bash -c "
|
||||
cd \"$INSTALL_DIR\"
|
||||
/usr/local/bin/node -e \"
|
||||
const { generateSecretKey, getPublicKey } = require('nostr-tools/pure');
|
||||
const fs = require('fs');
|
||||
const config = JSON.parse(fs.readFileSync('config.json', 'utf8'));
|
||||
const sk = generateSecretKey();
|
||||
const pk = getPublicKey(sk);
|
||||
config.thrower.privateKey = Buffer.from(sk).toString('hex');
|
||||
config.thrower.publicKey = pk;
|
||||
fs.writeFileSync('config.json', JSON.stringify(config, null, 2));
|
||||
console.log('Generated keypair:');
|
||||
console.log('Private key:', Buffer.from(sk).toString('hex'));
|
||||
console.log('Public key:', pk);
|
||||
\"
|
||||
"
|
||||
echo "✅ Keypair generated"
|
||||
fi
|
||||
|
||||
# Installation complete
|
||||
echo ""
|
||||
echo "🎉 Installation completed successfully!"
|
||||
echo ""
|
||||
echo "📋 Next steps:"
|
||||
echo " 1. Start the service: sudo systemctl start superball-thrower"
|
||||
echo " 2. Check status: sudo systemctl status superball-thrower"
|
||||
echo " 3. View logs: sudo journalctl -u superball-thrower -f"
|
||||
echo ""
|
||||
echo "📖 For more information, see the README.md file"
|
||||
echo ""
|
||||
echo "🔐 Security notes:"
|
||||
echo " - The daemon runs as user '$DAEMON_USER' with limited privileges"
|
||||
echo " - Configuration files are owned by the daemon user"
|
||||
echo " - Logs are written to $LOG_DIR"
|
||||
echo ""
|
||||
echo "⚙️ Configuration summary:"
|
||||
echo " - Thrower name: $THROWER_NAME"
|
||||
echo " - Description: $THROWER_DESCRIPTION"
|
||||
echo " - Config file: $INSTALL_DIR/config.json"
|
||||
echo ""
|
||||
21
thrower_daemon/install2.sh
Normal file
21
thrower_daemon/install2.sh
Normal file
@@ -0,0 +1,21 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Superball Thrower Daemon Installation Script
|
||||
# This script installs and configures the Superball Thrower daemon
|
||||
|
||||
# Download and install nvm:
|
||||
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.3/install.sh | bash
|
||||
|
||||
# in lieu of restarting the shell
|
||||
\. "$HOME/.nvm/nvm.sh"
|
||||
|
||||
# Download and install Node.js:
|
||||
nvm install 22
|
||||
|
||||
# Verify the Node.js version:
|
||||
node -v # Should print "v22.20.0".
|
||||
|
||||
# Verify npm version:
|
||||
npm -v # Should print "10.9.3".
|
||||
|
||||
|
||||
1
thrower_daemon/node_modules/.bin/nodemon
generated
vendored
Symbolic link
1
thrower_daemon/node_modules/.bin/nodemon
generated
vendored
Symbolic link
@@ -0,0 +1 @@
|
||||
../nodemon/bin/nodemon.js
|
||||
1
thrower_daemon/node_modules/.bin/nodetouch
generated
vendored
Symbolic link
1
thrower_daemon/node_modules/.bin/nodetouch
generated
vendored
Symbolic link
@@ -0,0 +1 @@
|
||||
../touch/bin/nodetouch.js
|
||||
1
thrower_daemon/node_modules/.bin/semver
generated
vendored
Symbolic link
1
thrower_daemon/node_modules/.bin/semver
generated
vendored
Symbolic link
@@ -0,0 +1 @@
|
||||
../semver/bin/semver.js
|
||||
528
thrower_daemon/node_modules/.package-lock.json
generated
vendored
Normal file
528
thrower_daemon/node_modules/.package-lock.json
generated
vendored
Normal file
@@ -0,0 +1,528 @@
|
||||
{
|
||||
"name": "superball-thrower-daemon",
|
||||
"version": "1.0.0",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"node_modules/@noble/ciphers": {
|
||||
"version": "0.5.3",
|
||||
"resolved": "https://registry.npmjs.org/@noble/ciphers/-/ciphers-0.5.3.tgz",
|
||||
"integrity": "sha512-B0+6IIHiqEs3BPMT0hcRmHvEj2QHOLu+uwt+tqDDeVd0oyVzh7BPrDcPjRnV1PV/5LaknXJJQvOuRGR0zQJz+w==",
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"url": "https://paulmillr.com/funding/"
|
||||
}
|
||||
},
|
||||
"node_modules/@noble/curves": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.2.0.tgz",
|
||||
"integrity": "sha512-oYclrNgRaM9SsBUBVbb8M6DTV7ZHRTKugureoYEncY5c65HOmRzvSiTE3y5CYaPYJA/GVkrhXEoF0M3Ya9PMnw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@noble/hashes": "1.3.2"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://paulmillr.com/funding/"
|
||||
}
|
||||
},
|
||||
"node_modules/@noble/curves/node_modules/@noble/hashes": {
|
||||
"version": "1.3.2",
|
||||
"resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.3.2.tgz",
|
||||
"integrity": "sha512-MVC8EAQp7MvEcm30KWENFjgR+Mkmf+D189XJTkFIlwohU5hcBbn1ZkKq7KVTi2Hme3PMGF390DaL52beVrIihQ==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 16"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://paulmillr.com/funding/"
|
||||
}
|
||||
},
|
||||
"node_modules/@noble/hashes": {
|
||||
"version": "1.3.1",
|
||||
"resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.3.1.tgz",
|
||||
"integrity": "sha512-EbqwksQwz9xDRGfDST86whPBgM65E0OH/pCgqW0GBVzO22bNE+NuIbeTb714+IfSjU3aRk47EUvXIb5bTsenKA==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 16"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://paulmillr.com/funding/"
|
||||
}
|
||||
},
|
||||
"node_modules/@scure/base": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/@scure/base/-/base-1.1.1.tgz",
|
||||
"integrity": "sha512-ZxOhsSyxYwLJj3pLZCefNitxsj093tb2vq90mp2txoYeBqbcjDjqFhyM8eUjq/uFm6zJ+mUuqxlS2FkuSY1MTA==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "individual",
|
||||
"url": "https://paulmillr.com/funding/"
|
||||
}
|
||||
],
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@scure/bip32": {
|
||||
"version": "1.3.1",
|
||||
"resolved": "https://registry.npmjs.org/@scure/bip32/-/bip32-1.3.1.tgz",
|
||||
"integrity": "sha512-osvveYtyzdEVbt3OfwwXFr4P2iVBL5u1Q3q4ONBfDY/UpOuXmOlbgwc1xECEboY8wIays8Yt6onaWMUdUbfl0A==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@noble/curves": "~1.1.0",
|
||||
"@noble/hashes": "~1.3.1",
|
||||
"@scure/base": "~1.1.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://paulmillr.com/funding/"
|
||||
}
|
||||
},
|
||||
"node_modules/@scure/bip32/node_modules/@noble/curves": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.1.0.tgz",
|
||||
"integrity": "sha512-091oBExgENk/kGj3AZmtBDMpxQPDtxQABR2B9lb1JbVTs6ytdzZNwvhxQ4MWasRNEzlbEH8jCWFCwhF/Obj5AA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@noble/hashes": "1.3.1"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://paulmillr.com/funding/"
|
||||
}
|
||||
},
|
||||
"node_modules/@scure/bip39": {
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/@scure/bip39/-/bip39-1.2.1.tgz",
|
||||
"integrity": "sha512-Z3/Fsz1yr904dduJD0NpiyRHhRYHdcnyh73FZWiV+/qhWi83wNJ3NWolYqCEN+ZWsUz2TWwajJggcRE9r1zUYg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@noble/hashes": "~1.3.0",
|
||||
"@scure/base": "~1.1.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://paulmillr.com/funding/"
|
||||
}
|
||||
},
|
||||
"node_modules/anymatch": {
|
||||
"version": "3.1.3",
|
||||
"resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz",
|
||||
"integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"normalize-path": "^3.0.0",
|
||||
"picomatch": "^2.0.4"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 8"
|
||||
}
|
||||
},
|
||||
"node_modules/balanced-match": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
|
||||
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/binary-extensions": {
|
||||
"version": "2.3.0",
|
||||
"resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz",
|
||||
"integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/brace-expansion": {
|
||||
"version": "1.1.12",
|
||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz",
|
||||
"integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"balanced-match": "^1.0.0",
|
||||
"concat-map": "0.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/braces": {
|
||||
"version": "3.0.3",
|
||||
"resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz",
|
||||
"integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"fill-range": "^7.1.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/chokidar": {
|
||||
"version": "3.6.0",
|
||||
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz",
|
||||
"integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"anymatch": "~3.1.2",
|
||||
"braces": "~3.0.2",
|
||||
"glob-parent": "~5.1.2",
|
||||
"is-binary-path": "~2.1.0",
|
||||
"is-glob": "~4.0.1",
|
||||
"normalize-path": "~3.0.0",
|
||||
"readdirp": "~3.6.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 8.10.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://paulmillr.com/funding/"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"fsevents": "~2.3.2"
|
||||
}
|
||||
},
|
||||
"node_modules/concat-map": {
|
||||
"version": "0.0.1",
|
||||
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
|
||||
"integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/debug": {
|
||||
"version": "4.4.3",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz",
|
||||
"integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"ms": "^2.1.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"supports-color": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/fill-range": {
|
||||
"version": "7.1.1",
|
||||
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
|
||||
"integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"to-regex-range": "^5.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/fsevents": {
|
||||
"version": "2.3.3",
|
||||
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
|
||||
"integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
|
||||
"dev": true,
|
||||
"hasInstallScript": true,
|
||||
"ideallyInert": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"darwin"
|
||||
],
|
||||
"engines": {
|
||||
"node": "^8.16.0 || ^10.6.0 || >=11.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/glob-parent": {
|
||||
"version": "5.1.2",
|
||||
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
|
||||
"integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"is-glob": "^4.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 6"
|
||||
}
|
||||
},
|
||||
"node_modules/has-flag": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
|
||||
"integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=4"
|
||||
}
|
||||
},
|
||||
"node_modules/ignore-by-default": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz",
|
||||
"integrity": "sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA==",
|
||||
"dev": true,
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/is-binary-path": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
|
||||
"integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"binary-extensions": "^2.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/is-extglob": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
|
||||
"integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/is-glob": {
|
||||
"version": "4.0.3",
|
||||
"resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
|
||||
"integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"is-extglob": "^2.1.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/is-number": {
|
||||
"version": "7.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
|
||||
"integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=0.12.0"
|
||||
}
|
||||
},
|
||||
"node_modules/minimatch": {
|
||||
"version": "3.1.2",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
|
||||
"integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"brace-expansion": "^1.1.7"
|
||||
},
|
||||
"engines": {
|
||||
"node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/ms": {
|
||||
"version": "2.1.3",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
|
||||
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/nodemon": {
|
||||
"version": "3.1.10",
|
||||
"resolved": "https://registry.npmjs.org/nodemon/-/nodemon-3.1.10.tgz",
|
||||
"integrity": "sha512-WDjw3pJ0/0jMFmyNDp3gvY2YizjLmmOUQo6DEBY+JgdvW/yQ9mEeSw6H5ythl5Ny2ytb7f9C2nIbjSxMNzbJXw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"chokidar": "^3.5.2",
|
||||
"debug": "^4",
|
||||
"ignore-by-default": "^1.0.1",
|
||||
"minimatch": "^3.1.2",
|
||||
"pstree.remy": "^1.1.8",
|
||||
"semver": "^7.5.3",
|
||||
"simple-update-notifier": "^2.0.0",
|
||||
"supports-color": "^5.5.0",
|
||||
"touch": "^3.1.0",
|
||||
"undefsafe": "^2.0.5"
|
||||
},
|
||||
"bin": {
|
||||
"nodemon": "bin/nodemon.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/nodemon"
|
||||
}
|
||||
},
|
||||
"node_modules/normalize-path": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
|
||||
"integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/nostr-tools": {
|
||||
"version": "2.17.0",
|
||||
"resolved": "https://registry.npmjs.org/nostr-tools/-/nostr-tools-2.17.0.tgz",
|
||||
"integrity": "sha512-lrvHM7cSaGhz7F0YuBvgHMoU2s8/KuThihDoOYk8w5gpVHTy0DeUCAgCN8uLGeuSl5MAWekJr9Dkfo5HClqO9w==",
|
||||
"license": "Unlicense",
|
||||
"dependencies": {
|
||||
"@noble/ciphers": "^0.5.1",
|
||||
"@noble/curves": "1.2.0",
|
||||
"@noble/hashes": "1.3.1",
|
||||
"@scure/base": "1.1.1",
|
||||
"@scure/bip32": "1.3.1",
|
||||
"@scure/bip39": "1.2.1",
|
||||
"nostr-wasm": "0.1.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"typescript": ">=5.0.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"typescript": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/nostr-wasm": {
|
||||
"version": "0.1.0",
|
||||
"resolved": "https://registry.npmjs.org/nostr-wasm/-/nostr-wasm-0.1.0.tgz",
|
||||
"integrity": "sha512-78BTryCLcLYv96ONU8Ws3Q1JzjlAt+43pWQhIl86xZmWeegYCNLPml7yQ+gG3vR6V5h4XGj+TxO+SS5dsThQIA==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/picomatch": {
|
||||
"version": "2.3.1",
|
||||
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
|
||||
"integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=8.6"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/jonschlinkert"
|
||||
}
|
||||
},
|
||||
"node_modules/pstree.remy": {
|
||||
"version": "1.1.8",
|
||||
"resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.8.tgz",
|
||||
"integrity": "sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/readdirp": {
|
||||
"version": "3.6.0",
|
||||
"resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
|
||||
"integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"picomatch": "^2.2.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/semver": {
|
||||
"version": "7.7.2",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz",
|
||||
"integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"bin": {
|
||||
"semver": "bin/semver.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/simple-update-notifier": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/simple-update-notifier/-/simple-update-notifier-2.0.0.tgz",
|
||||
"integrity": "sha512-a2B9Y0KlNXl9u/vsW6sTIu9vGEpfKu2wRV6l1H3XEas/0gUIzGzBoP/IouTcUQbm9JWZLH3COxyn03TYlFax6w==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"semver": "^7.5.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/supports-color": {
|
||||
"version": "5.5.0",
|
||||
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
|
||||
"integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"has-flag": "^3.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=4"
|
||||
}
|
||||
},
|
||||
"node_modules/to-regex-range": {
|
||||
"version": "5.0.1",
|
||||
"resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
|
||||
"integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"is-number": "^7.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8.0"
|
||||
}
|
||||
},
|
||||
"node_modules/touch": {
|
||||
"version": "3.1.1",
|
||||
"resolved": "https://registry.npmjs.org/touch/-/touch-3.1.1.tgz",
|
||||
"integrity": "sha512-r0eojU4bI8MnHr8c5bNo7lJDdI2qXlWWJk6a9EAFG7vbhTjElYhBVS3/miuE0uOuoLdb8Mc/rVfsmm6eo5o9GA==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"bin": {
|
||||
"nodetouch": "bin/nodetouch.js"
|
||||
}
|
||||
},
|
||||
"node_modules/undefsafe": {
|
||||
"version": "2.0.5",
|
||||
"resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.5.tgz",
|
||||
"integrity": "sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/ws": {
|
||||
"version": "8.18.3",
|
||||
"resolved": "https://registry.npmjs.org/ws/-/ws-8.18.3.tgz",
|
||||
"integrity": "sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=10.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"bufferutil": "^4.0.1",
|
||||
"utf-8-validate": ">=5.0.2"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"bufferutil": {
|
||||
"optional": true
|
||||
},
|
||||
"utf-8-validate": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
22
thrower_daemon/node_modules/@noble/ciphers/LICENSE
generated
vendored
Normal file
22
thrower_daemon/node_modules/@noble/ciphers/LICENSE
generated
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2022 Paul Miller (https://paulmillr.com)
|
||||
Copyright (c) 2016 Thomas Pornin <pornin@bolet.org>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the “Software”), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
655
thrower_daemon/node_modules/@noble/ciphers/README.md
generated
vendored
Normal file
655
thrower_daemon/node_modules/@noble/ciphers/README.md
generated
vendored
Normal file
@@ -0,0 +1,655 @@
|
||||
# noble-ciphers
|
||||
|
||||
Auditable & minimal JS implementation of Salsa20, ChaCha and AES.
|
||||
|
||||
- 🔒 Auditable
|
||||
- 🔻 Tree-shaking-friendly: use only what's necessary, other code won't be included
|
||||
- 🏎 [Ultra-fast](#speed), hand-optimized for caveats of JS engines
|
||||
- 🔍 Unique tests ensure correctness: property-based, cross-library and Wycheproof vectors
|
||||
- 💼 AES: ECB, CBC, CTR, CFB, GCM, SIV (nonce misuse-resistant)
|
||||
- 💃 Salsa20, ChaCha, XSalsa20, XChaCha, Poly1305, ChaCha8, ChaCha12
|
||||
- 🥈 Two AES implementations: choose between friendly webcrypto wrapper and pure JS one
|
||||
- 🪶 45KB (8KB gzipped) for everything, 10KB (3KB gzipped) for ChaCha build
|
||||
|
||||
For discussions, questions and support, visit
|
||||
[GitHub Discussions](https://github.com/paulmillr/noble-ciphers/discussions)
|
||||
section of the repository.
|
||||
|
||||
### This library belongs to _noble_ cryptography
|
||||
|
||||
> **noble cryptography** — high-security, easily auditable set of contained cryptographic libraries and tools.
|
||||
|
||||
- Zero or minimal dependencies
|
||||
- Highly readable TypeScript / JS code
|
||||
- PGP-signed releases and transparent NPM builds
|
||||
- All libraries:
|
||||
[ciphers](https://github.com/paulmillr/noble-ciphers),
|
||||
[curves](https://github.com/paulmillr/noble-curves),
|
||||
[hashes](https://github.com/paulmillr/noble-hashes),
|
||||
[post-quantum](https://github.com/paulmillr/noble-post-quantum),
|
||||
4kb [secp256k1](https://github.com/paulmillr/noble-secp256k1) /
|
||||
[ed25519](https://github.com/paulmillr/noble-ed25519)
|
||||
- [Check out homepage](https://paulmillr.com/noble/)
|
||||
for reading resources, documentation and apps built with noble
|
||||
|
||||
## Usage
|
||||
|
||||
> npm install @noble/ciphers
|
||||
|
||||
We support all major platforms and runtimes.
|
||||
For [Deno](https://deno.land), ensure to use
|
||||
[npm specifier](https://deno.land/manual@v1.28.0/node/npm_specifiers).
|
||||
For React Native, you may need a
|
||||
[polyfill for getRandomValues](https://github.com/LinusU/react-native-get-random-values).
|
||||
A standalone file
|
||||
[noble-ciphers.js](https://github.com/paulmillr/noble-ciphers/releases) is also available.
|
||||
|
||||
```js
|
||||
// import * from '@noble/ciphers'; // Error: use sub-imports, to ensure small app size
|
||||
import { xchacha20poly1305 } from '@noble/ciphers/chacha';
|
||||
// import { xchacha20poly1305 } from 'npm:@noble/ciphers@0.5.0/chacha'; // Deno
|
||||
```
|
||||
|
||||
- [Examples](#examples)
|
||||
- [Encrypt with XChaCha20-Poly1305](#encrypt-with-xchacha20-poly1305)
|
||||
- [Encrypt with AES-256-GCM](#encrypt-with-aes-256-gcm)
|
||||
- [Use existing key instead of a new one](#use-existing-key-instead-of-a-new-one)
|
||||
- [Encrypt without nonce](#encrypt-without-nonce)
|
||||
- [Use same array for input and output](#use-same-array-for-input-and-output)
|
||||
- [All imports](#all-imports)
|
||||
- [Implementations](#implementations)
|
||||
- [Salsa20](#salsa)
|
||||
- [ChaCha](#chacha)
|
||||
- [AES](#aes)
|
||||
- [Webcrypto AES](#webcrypto-aes)
|
||||
- [Poly1305, GHash, Polyval](#poly1305-ghash-polyval)
|
||||
- [FF1 format-preserving encryption](#ff1)
|
||||
- [Managed nonces](#managed-nonces)
|
||||
- [Guidance](#guidance)
|
||||
- [Which cipher should I pick?](#which-cipher-should-i-pick)
|
||||
- [How to encrypt properly](#how-to-encrypt-properly)
|
||||
- [Nonces](#nonces)
|
||||
- [Encryption limits](#encryption-limits)
|
||||
- [AES internals and block modes](#aes-internals-and-block-modes)
|
||||
- [Security](#security)
|
||||
- [Speed](#speed)
|
||||
- [Upgrading](#upgrading)
|
||||
- [Contributing & testing](#contributing--testing)
|
||||
- [Resources](#resources)
|
||||
|
||||
## Examples
|
||||
|
||||
#### Encrypt with XChaCha20-Poly1305
|
||||
|
||||
```js
|
||||
import { xchacha20poly1305 } from '@noble/ciphers/chacha';
|
||||
import { utf8ToBytes } from '@noble/ciphers/utils';
|
||||
import { randomBytes } from '@noble/ciphers/webcrypto';
|
||||
const key = randomBytes(32);
|
||||
const nonce = randomBytes(24);
|
||||
const chacha = xchacha20poly1305(key, nonce);
|
||||
const data = utf8ToBytes('hello, noble');
|
||||
const ciphertext = chacha.encrypt(data);
|
||||
const data_ = chacha.decrypt(ciphertext); // utils.bytesToUtf8(data_) === data
|
||||
```
|
||||
|
||||
#### Encrypt with AES-256-GCM
|
||||
|
||||
```js
|
||||
import { gcm } from '@noble/ciphers/aes';
|
||||
import { utf8ToBytes } from '@noble/ciphers/utils';
|
||||
import { randomBytes } from '@noble/ciphers/webcrypto';
|
||||
const key = randomBytes(32);
|
||||
const nonce = randomBytes(24);
|
||||
const aes = gcm(key, nonce);
|
||||
const data = utf8ToBytes('hello, noble');
|
||||
const ciphertext = aes.encrypt(data);
|
||||
const data_ = aes.decrypt(ciphertext); // utils.bytesToUtf8(data_) === data
|
||||
```
|
||||
|
||||
#### Use existing key instead of a new one
|
||||
|
||||
```js
|
||||
const key = new Uint8Array([
|
||||
169, 88, 160, 139, 168, 29, 147, 196, 14, 88, 237, 76, 243, 177, 109, 140, 195, 140, 80, 10, 216,
|
||||
134, 215, 71, 191, 48, 20, 104, 189, 37, 38, 55,
|
||||
]);
|
||||
const nonce = new Uint8Array([
|
||||
180, 90, 27, 63, 160, 191, 150, 33, 67, 212, 86, 71, 144, 6, 200, 102, 218, 32, 23, 147, 8, 41,
|
||||
147, 11,
|
||||
]);
|
||||
// or, hex:
|
||||
import { hexToBytes } from '@noble/ciphers/utils';
|
||||
const key2 = hexToBytes('4b7f89bac90a1086fef73f5da2cbe93b2fae9dfbf7678ae1f3e75fd118ddf999');
|
||||
const nonce2 = hexToBytes('9610467513de0bbd7c4cc2c3c64069f1802086fbd3232b13');
|
||||
```
|
||||
|
||||
#### Encrypt without nonce
|
||||
|
||||
```js
|
||||
import { xchacha20poly1305 } from '@noble/ciphers/chacha';
|
||||
import { managedNonce } from '@noble/ciphers/webcrypto';
|
||||
import { hexToBytes, utf8ToBytes } from '@noble/ciphers/utils';
|
||||
const key = hexToBytes('fa686bfdffd3758f6377abbc23bf3d9bdc1a0dda4a6e7f8dbdd579fa1ff6d7e1');
|
||||
const chacha = managedNonce(xchacha20poly1305)(key); // manages nonces for you
|
||||
const data = utf8ToBytes('hello, noble');
|
||||
const ciphertext = chacha.encrypt(data);
|
||||
const data_ = chacha.decrypt(ciphertext);
|
||||
```
|
||||
|
||||
#### Use same array for input and output
|
||||
|
||||
```js
|
||||
import { chacha20poly1305 } from '@noble/ciphers/chacha';
|
||||
import { utf8ToBytes } from '@noble/ciphers/utils';
|
||||
import { randomBytes } from '@noble/ciphers/webcrypto';
|
||||
|
||||
const key = randomBytes(32);
|
||||
const nonce = randomBytes(12);
|
||||
const buf = new Uint8Array(12 + 16);
|
||||
const _data = utf8ToBytes('hello, noble');
|
||||
buf.set(_data, 0); // first 12 bytes
|
||||
const _12b = buf.subarray(0, 12);
|
||||
|
||||
const chacha = chacha20poly1305(key, nonce);
|
||||
chacha.encrypt(_12b, buf);
|
||||
chacha.decrypt(buf, _12b); // _12b now same as _data
|
||||
```
|
||||
|
||||
#### All imports
|
||||
|
||||
```js
|
||||
import { gcm, siv } from '@noble/ciphers/aes';
|
||||
import { xsalsa20poly1305 } from '@noble/ciphers/salsa';
|
||||
import { chacha20poly1305, xchacha20poly1305 } from '@noble/ciphers/chacha';
|
||||
|
||||
// Unauthenticated encryption: make sure to use HMAC or similar
|
||||
import { ctr, cfb, cbc, ecb } from '@noble/ciphers/aes';
|
||||
import { salsa20, xsalsa20 } from '@noble/ciphers/salsa';
|
||||
import { chacha20, xchacha20, chacha8, chacha12 } from '@noble/ciphers/chacha';
|
||||
|
||||
// Utilities
|
||||
import { bytesToHex, hexToBytes, bytesToUtf8, utf8ToBytes } from '@noble/ciphers/utils';
|
||||
import { managedNonce, randomBytes } from '@noble/ciphers/webcrypto';
|
||||
```
|
||||
|
||||
## Implementations
|
||||
|
||||
### Salsa
|
||||
|
||||
```js
|
||||
import { xsalsa20poly1305 } from '@noble/ciphers/salsa';
|
||||
import { secretbox } from '@noble/ciphers/salsa'; // == xsalsa20poly1305
|
||||
import { salsa20, xsalsa20 } from '@noble/ciphers/salsa';
|
||||
```
|
||||
|
||||
[Salsa20](https://cr.yp.to/snuffle.html) stream cipher was released in 2005.
|
||||
Salsa's goal was to implement AES replacement that does not rely on S-Boxes,
|
||||
which are hard to implement in a constant-time manner.
|
||||
Salsa20 is usually faster than AES, a big deal on slow, budget mobile phones.
|
||||
|
||||
[XSalsa20](https://cr.yp.to/snuffle/xsalsa-20110204.pdf), extended-nonce
|
||||
variant was released in 2008. It switched nonces from 96-bit to 192-bit,
|
||||
and became safe to be picked at random.
|
||||
|
||||
Nacl / Libsodium popularized term "secretbox", a simple black-box
|
||||
authenticated encryption. Secretbox is just xsalsa20-poly1305. We provide the
|
||||
alias and corresponding seal / open methods. We don't provide "box" or "sealedbox".
|
||||
|
||||
Check out [PDF](https://cr.yp.to/snuffle/salsafamily-20071225.pdf) and
|
||||
[wiki](https://en.wikipedia.org/wiki/Salsa20).
|
||||
|
||||
### ChaCha
|
||||
|
||||
```js
|
||||
import { chacha20poly1305, xchacha20poly1305 } from '@noble/ciphers/chacha';
|
||||
import { chacha20, xchacha20, chacha8, chacha12 } from '@noble/ciphers/chacha';
|
||||
```
|
||||
|
||||
[ChaCha20](https://cr.yp.to/chacha.html) stream cipher was released
|
||||
in 2008. ChaCha aims to increase the diffusion per round, but had slightly less
|
||||
cryptanalysis. It was standardized in
|
||||
[RFC 8439](https://datatracker.ietf.org/doc/html/rfc8439) and is now used in TLS 1.3.
|
||||
|
||||
[XChaCha20](https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-xchacha)
|
||||
extended-nonce variant is also provided. Similar to XSalsa, it's safe to use with
|
||||
randomly-generated nonces.
|
||||
|
||||
Check out [PDF](http://cr.yp.to/chacha/chacha-20080128.pdf) and [wiki](https://en.wikipedia.org/wiki/Salsa20).
|
||||
|
||||
### AES
|
||||
|
||||
```js
|
||||
import { gcm, siv, ctr, cfb, cbc, ecb } from '@noble/ciphers/aes';
|
||||
import { randomBytes } from '@noble/ciphers/webcrypto';
|
||||
const plaintext = new Uint8Array(32).fill(16);
|
||||
const key = randomBytes(32); // 24 for AES-192, 16 for AES-128
|
||||
for (let cipher of [gcm, siv]) {
|
||||
const stream = cipher(key, randomBytes(12));
|
||||
const ciphertext_ = stream.encrypt(plaintext);
|
||||
const plaintext_ = stream.decrypt(ciphertext_);
|
||||
}
|
||||
for (const cipher of [ctr, cbc, cbc]) {
|
||||
const stream = cipher(key, randomBytes(16));
|
||||
const ciphertext_ = stream.encrypt(plaintext);
|
||||
const plaintext_ = stream.decrypt(ciphertext_);
|
||||
}
|
||||
for (const cipher of [ecb]) {
|
||||
const stream = cipher(key);
|
||||
const ciphertext_ = stream.encrypt(plaintext);
|
||||
const plaintext_ = stream.decrypt(ciphertext_);
|
||||
}
|
||||
```
|
||||
|
||||
[AES](https://en.wikipedia.org/wiki/Advanced_Encryption_Standard)
|
||||
is a variant of Rijndael block cipher, standardized by NIST in 2001.
|
||||
We provide the fastest available pure JS implementation.
|
||||
|
||||
We support AES-128, AES-192 and AES-256: the mode is selected dynamically,
|
||||
based on key length (16, 24, 32).
|
||||
|
||||
[AES-GCM-SIV](https://en.wikipedia.org/wiki/AES-GCM-SIV)
|
||||
nonce-misuse-resistant mode is also provided. It's recommended to use it,
|
||||
to prevent catastrophic consequences of nonce reuse. Our implementation of SIV
|
||||
has the same speed as GCM: there is no performance hit.
|
||||
|
||||
Check out [AES internals and block modes](#aes-internals-and-block-modes).
|
||||
|
||||
### Webcrypto AES
|
||||
|
||||
```js
|
||||
import { gcm, ctr, cbc, randomBytes } from '@noble/ciphers/webcrypto';
|
||||
const plaintext = new Uint8Array(32).fill(16);
|
||||
const key = randomBytes(32);
|
||||
for (const cipher of [gcm]) {
|
||||
const stream = cipher(key, randomBytes(12));
|
||||
const ciphertext_ = await stream.encrypt(plaintext);
|
||||
const plaintext_ = await stream.decrypt(ciphertext_);
|
||||
}
|
||||
for (const cipher of [ctr, cbc]) {
|
||||
const stream = cipher(key, randomBytes(16));
|
||||
const ciphertext_ = await stream.encrypt(plaintext);
|
||||
const plaintext_ = await stream.decrypt(ciphertext_);
|
||||
}
|
||||
```
|
||||
|
||||
We also have a separate wrapper over WebCrypto built-in.
|
||||
|
||||
It's the same as using `crypto.subtle`, but with massively simplified API.
|
||||
|
||||
Unlike pure js version, it's asynchronous.
|
||||
|
||||
### Poly1305, GHash, Polyval
|
||||
|
||||
```js
|
||||
import { poly1305 } from '@noble/ciphers/_poly1305';
|
||||
import { ghash, polyval } from '@noble/ciphers/_polyval';
|
||||
```
|
||||
|
||||
We expose polynomial-evaluation MACs: [Poly1305](https://cr.yp.to/mac.html),
|
||||
AES-GCM's [GHash](https://en.wikipedia.org/wiki/Galois/Counter_Mode) and
|
||||
AES-SIV's [Polyval](https://en.wikipedia.org/wiki/AES-GCM-SIV).
|
||||
|
||||
Poly1305 ([PDF](https://cr.yp.to/mac/poly1305-20050329.pdf),
|
||||
[wiki](https://en.wikipedia.org/wiki/Poly1305))
|
||||
is a fast and parallel secret-key message-authentication code suitable for
|
||||
a wide variety of applications. It was standardized in
|
||||
[RFC 8439](https://datatracker.ietf.org/doc/html/rfc8439) and is now used in TLS 1.3.
|
||||
|
||||
Polynomial MACs are not perfect for every situation:
|
||||
they lack Random Key Robustness: the MAC can be forged, and can't
|
||||
be used in PAKE schemes. See
|
||||
[invisible salamanders attack](https://keymaterial.net/2020/09/07/invisible-salamanders-in-aes-gcm-siv/).
|
||||
To combat invisible salamanders, `hash(key)` can be included in ciphertext,
|
||||
however, this would violate ciphertext indistinguishability:
|
||||
an attacker would know which key was used - so `HKDF(key, i)`
|
||||
could be used instead.
|
||||
|
||||
### FF1
|
||||
|
||||
Format-preserving encryption algorithm (FPE-FF1) specified in NIST Special Publication 800-38G.
|
||||
[See more info](https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-38G.pdf).
|
||||
|
||||
### Managed nonces
|
||||
|
||||
```js
|
||||
import { managedNonce } from '@noble/ciphers/webcrypto';
|
||||
import { gcm, siv, ctr, cbc, cbc, ecb } from '@noble/ciphers/aes';
|
||||
import { xsalsa20poly1305 } from '@noble/ciphers/salsa';
|
||||
import { chacha20poly1305, xchacha20poly1305 } from '@noble/ciphers/chacha';
|
||||
|
||||
const wgcm = managedNonce(gcm);
|
||||
const wsiv = managedNonce(siv);
|
||||
const wcbc = managedNonce(cbc);
|
||||
const wctr = managedNonce(ctr);
|
||||
const wsalsapoly = managedNonce(xsalsa20poly1305);
|
||||
const wchacha = managedNonce(chacha20poly1305);
|
||||
const wxchacha = managedNonce(xchacha20poly1305);
|
||||
|
||||
// Now:
|
||||
const encrypted = wgcm(key).encrypt(data); // no nonces
|
||||
```
|
||||
|
||||
We provide API that manages nonce internally instead of exposing them to library's user.
|
||||
|
||||
For `encrypt`, a `nonceBytes`-length buffer is fetched from CSPRNG and prenended to encrypted ciphertext.
|
||||
|
||||
For `decrypt`, first `nonceBytes` of ciphertext are treated as nonce.
|
||||
|
||||
## Guidance
|
||||
|
||||
### Which cipher should I pick?
|
||||
|
||||
XChaCha20-Poly1305 is the safest bet these days.
|
||||
AES-GCM-SIV is the second safest.
|
||||
AES-GCM is the third.
|
||||
|
||||
### How to encrypt properly
|
||||
|
||||
- Use unpredictable key with enough entropy
|
||||
- Random key must be using cryptographically secure random number generator (CSPRNG), not `Math.random` etc.
|
||||
- Non-random key generated from KDF is fine
|
||||
- Re-using key is fine, but be aware of rules for cryptographic key wear-out and [encryption limits](#encryption-limits)
|
||||
- Use new nonce every time and [don't repeat it](#nonces)
|
||||
- chacha and salsa20 are fine for sequential counters that _never_ repeat: `01, 02...`
|
||||
- xchacha and xsalsa20 should be used for random nonces instead
|
||||
- Prefer authenticated encryption (AEAD)
|
||||
- HMAC+ChaCha / HMAC+AES / chacha20poly1305 / aes-gcm is good
|
||||
- chacha20 without poly1305 or hmac / aes-ctr / aes-cbc is bad
|
||||
- Flipping bits or ciphertext substitution won't be detected in unauthenticated ciphers
|
||||
- Don't re-use keys between different protocols
|
||||
- For example, using secp256k1 key in AES is bad
|
||||
- Use hkdf or, at least, a hash function to create sub-key instead
|
||||
|
||||
### Nonces
|
||||
|
||||
Most ciphers need a key and a nonce (aka initialization vector / IV) to encrypt a data:
|
||||
|
||||
ciphertext = encrypt(plaintext, key, nonce)
|
||||
|
||||
Repeating (key, nonce) pair with different plaintexts would allow an attacker to decrypt it:
|
||||
|
||||
ciphertext_a = encrypt(plaintext_a, key, nonce)
|
||||
ciphertext_b = encrypt(plaintext_b, key, nonce)
|
||||
stream_diff = xor(ciphertext_a, ciphertext_b) # Break encryption
|
||||
|
||||
So, you can't repeat nonces. One way of doing so is using counters:
|
||||
|
||||
for i in 0..:
|
||||
ciphertext[i] = encrypt(plaintexts[i], key, i)
|
||||
|
||||
Another is generating random nonce every time:
|
||||
|
||||
for i in 0..:
|
||||
rand_nonces[i] = random()
|
||||
ciphertext[i] = encrypt(plaintexts[i], key, rand_nonces[i])
|
||||
|
||||
Counters are OK, but it's not always possible to store current counter value:
|
||||
e.g. in decentralized, unsyncable systems.
|
||||
|
||||
Randomness is OK, but there's a catch:
|
||||
ChaCha20 and AES-GCM use 96-bit / 12-byte nonces, which implies
|
||||
higher chance of collision. In the example above,
|
||||
`random()` can collide and produce repeating nonce.
|
||||
|
||||
To safely use random nonces, utilize XSalsa20 or XChaCha:
|
||||
they increased nonce length to 192-bit, minimizing a chance of collision.
|
||||
AES-SIV is also fine. In situations where you can't use eXtended-nonce
|
||||
algorithms, key rotation is advised. hkdf would work great for this case.
|
||||
|
||||
### Encryption limits
|
||||
|
||||
A "protected message" would mean a probability of `2**-50` that a passive attacker
|
||||
successfully distinguishes the ciphertext outputs of the AEAD scheme from the outputs
|
||||
of a random function. See [draft-irtf-cfrg-aead-limits](https://datatracker.ietf.org/doc/draft-irtf-cfrg-aead-limits/) for details.
|
||||
|
||||
- Max message size:
|
||||
- AES-GCM: ~68GB, `2**36-256`
|
||||
- Salsa, ChaCha, XSalsa, XChaCha: ~256GB, `2**38-64`
|
||||
- Max amount of protected messages, under same key:
|
||||
- AES-GCM: `2**32.5`
|
||||
- Salsa, ChaCha: `2**46`, but only integrity is affected, not confidentiality
|
||||
- XSalsa, XChaCha: `2**72`
|
||||
- Max amount of protected messages, across all keys:
|
||||
- AES-GCM: `2**69/B` where B is max blocks encrypted by a key. Meaning
|
||||
`2**59` for 1KB, `2**49` for 1MB, `2**39` for 1GB
|
||||
- Salsa, ChaCha, XSalsa, XChaCha: `2**100`
|
||||
|
||||
##### AES internals and block modes
|
||||
|
||||
`cipher = encrypt(block, key)`. Data is split into 128-bit blocks. Encrypted in 10/12/14 rounds (128/192/256bit). Every round does:
|
||||
|
||||
1. **S-box**, table substitution
|
||||
2. **Shift rows**, cyclic shift left of all rows of data array
|
||||
3. **Mix columns**, multiplying every column by fixed polynomial
|
||||
4. **Add round key**, round_key xor i-th column of array
|
||||
|
||||
For non-deterministic (not ECB) schemes, initialization vector (IV) is mixed to block/key;
|
||||
and each new round either depends on previous block's key, or on some counter.
|
||||
|
||||
- ECB — simple deterministic replacement. Dangerous: always map x to y. See [AES Penguin](https://words.filippo.io/the-ecb-penguin/)
|
||||
- CBC — key is previous round’s block. Hard to use: need proper padding, also needs MAC
|
||||
- CTR — counter, allows to create streaming cipher. Requires good IV. Parallelizable. OK, but no MAC
|
||||
- GCM — modern CTR, parallel, with MAC
|
||||
- SIV — synthetic initialization vector, nonce-misuse-resistant. Guarantees that, when a nonce is repeated,
|
||||
the only security loss is that identical plaintexts will produce identical ciphertexts.
|
||||
- XTS — used in hard drives. Similar to ECB (deterministic), but has `[i][j]`
|
||||
tweak arguments corresponding to sector i and 16-byte block (part of sector) j. Not authenticated!
|
||||
|
||||
GCM / SIV are not ideal:
|
||||
|
||||
- Conservative key wear-out is `2**32` (4B) msgs
|
||||
- MAC can be forged: see Poly1305 section above. Same for SIV
|
||||
|
||||
## Security
|
||||
|
||||
The library has not been independently audited yet.
|
||||
|
||||
It is tested against property-based, cross-library and Wycheproof vectors,
|
||||
and has fuzzing by [Guido Vranken's cryptofuzz](https://github.com/guidovranken/cryptofuzz).
|
||||
|
||||
If you see anything unusual: investigate and report.
|
||||
|
||||
### Constant-timeness
|
||||
|
||||
_JIT-compiler_ and _Garbage Collector_ make "constant time" extremely hard to
|
||||
achieve [timing attack](https://en.wikipedia.org/wiki/Timing_attack) resistance
|
||||
in a scripting language. Which means _any other JS library can't have
|
||||
constant-timeness_. Even statically typed Rust, a language without GC,
|
||||
[makes it harder to achieve constant-time](https://www.chosenplaintext.ca/open-source/rust-timing-shield/security)
|
||||
for some cases. If your goal is absolute security, don't use any JS lib — including bindings to native ones.
|
||||
Use low-level libraries & languages. Nonetheless we're targetting algorithmic constant time.
|
||||
|
||||
AES uses T-tables, which means it can't be done in constant-time in JS.
|
||||
|
||||
### Supply chain security
|
||||
|
||||
- **Commits** are signed with PGP keys, to prevent forgery. Make sure to verify commit signatures.
|
||||
- **Releases** are transparent and built on GitHub CI. Make sure to verify [provenance](https://docs.npmjs.com/generating-provenance-statements) logs
|
||||
- **Rare releasing** is followed to ensure less re-audit need for end-users
|
||||
- **Dependencies** are minimized and locked-down:
|
||||
- If your app has 500 dependencies, any dep could get hacked and you'll be downloading
|
||||
malware with every install. We make sure to use as few dependencies as possible
|
||||
- We prevent automatic dependency updates by locking-down version ranges. Every update is checked with `npm-diff`
|
||||
- **Dev Dependencies** are only used if you want to contribute to the repo. They are disabled for end-users:
|
||||
- scure-base, micro-bmark and micro-should are developed by the same author and follow identical security practices
|
||||
- prettier (linter), fast-check (property-based testing) and typescript are used for code quality, vector generation and ts compilation. The packages are big, which makes it hard to audit their source code thoroughly and fully
|
||||
|
||||
### Randomness
|
||||
|
||||
We're deferring to built-in
|
||||
[crypto.getRandomValues](https://developer.mozilla.org/en-US/docs/Web/API/Crypto/getRandomValues)
|
||||
which is considered cryptographically secure (CSPRNG).
|
||||
|
||||
In the past, browsers had bugs that made it weak: it may happen again.
|
||||
Implementing a userspace CSPRNG to get resilient to the weakness
|
||||
is even worse: there is no reliable userspace source of quality entropy.
|
||||
|
||||
## Speed
|
||||
|
||||
To summarize, noble is the fastest JS implementation of Salsa, ChaCha and AES.
|
||||
|
||||
You can gain additional speed-up and
|
||||
avoid memory allocations by passing `output`
|
||||
uint8array into encrypt / decrypt methods.
|
||||
|
||||
Benchmark results on Apple M2 with node v20:
|
||||
|
||||
```
|
||||
encrypt (64B)
|
||||
├─xsalsa20poly1305 x 485,672 ops/sec @ 2μs/op
|
||||
├─chacha20poly1305 x 466,200 ops/sec @ 2μs/op
|
||||
├─xchacha20poly1305 x 312,500 ops/sec @ 3μs/op
|
||||
├─aes-256-gcm x 151,057 ops/sec @ 6μs/op
|
||||
└─aes-256-gcm-siv x 124,984 ops/sec @ 8μs/op
|
||||
encrypt (1KB)
|
||||
├─xsalsa20poly1305 x 146,477 ops/sec @ 6μs/op
|
||||
├─chacha20poly1305 x 145,518 ops/sec @ 6μs/op
|
||||
├─xchacha20poly1305 x 126,119 ops/sec @ 7μs/op
|
||||
├─aes-256-gcm x 43,207 ops/sec @ 23μs/op
|
||||
└─aes-256-gcm-siv x 39,363 ops/sec @ 25μs/op
|
||||
encrypt (8KB)
|
||||
├─xsalsa20poly1305 x 23,773 ops/sec @ 42μs/op
|
||||
├─chacha20poly1305 x 24,134 ops/sec @ 41μs/op
|
||||
├─xchacha20poly1305 x 23,520 ops/sec @ 42μs/op
|
||||
├─aes-256-gcm x 8,420 ops/sec @ 118μs/op
|
||||
└─aes-256-gcm-siv x 8,126 ops/sec @ 123μs/op
|
||||
encrypt (1MB)
|
||||
├─xsalsa20poly1305 x 195 ops/sec @ 5ms/op
|
||||
├─chacha20poly1305 x 199 ops/sec @ 5ms/op
|
||||
├─xchacha20poly1305 x 198 ops/sec @ 5ms/op
|
||||
├─aes-256-gcm x 76 ops/sec @ 13ms/op
|
||||
└─aes-256-gcm-siv x 78 ops/sec @ 12ms/op
|
||||
```
|
||||
|
||||
Unauthenticated encryption:
|
||||
|
||||
```
|
||||
encrypt (64B)
|
||||
├─salsa x 1,287,001 ops/sec @ 777ns/op
|
||||
├─chacha x 1,555,209 ops/sec @ 643ns/op
|
||||
├─xsalsa x 938,086 ops/sec @ 1μs/op
|
||||
└─xchacha x 920,810 ops/sec @ 1μs/op
|
||||
encrypt (1KB)
|
||||
├─salsa x 353,107 ops/sec @ 2μs/op
|
||||
├─chacha x 377,216 ops/sec @ 2μs/op
|
||||
├─xsalsa x 331,674 ops/sec @ 3μs/op
|
||||
└─xchacha x 336,247 ops/sec @ 2μs/op
|
||||
encrypt (8KB)
|
||||
├─salsa x 57,084 ops/sec @ 17μs/op
|
||||
├─chacha x 59,520 ops/sec @ 16μs/op
|
||||
├─xsalsa x 57,097 ops/sec @ 17μs/op
|
||||
└─xchacha x 58,278 ops/sec @ 17μs/op
|
||||
encrypt (1MB)
|
||||
├─salsa x 479 ops/sec @ 2ms/op
|
||||
├─chacha x 491 ops/sec @ 2ms/op
|
||||
├─xsalsa x 483 ops/sec @ 2ms/op
|
||||
└─xchacha x 492 ops/sec @ 2ms/op
|
||||
|
||||
AES
|
||||
encrypt (64B)
|
||||
├─ctr-256 x 689,179 ops/sec @ 1μs/op
|
||||
├─cbc-256 x 639,795 ops/sec @ 1μs/op
|
||||
└─ecb-256 x 668,449 ops/sec @ 1μs/op
|
||||
encrypt (1KB)
|
||||
├─ctr-256 x 93,668 ops/sec @ 10μs/op
|
||||
├─cbc-256 x 94,428 ops/sec @ 10μs/op
|
||||
└─ecb-256 x 151,699 ops/sec @ 6μs/op
|
||||
encrypt (8KB)
|
||||
├─ctr-256 x 13,342 ops/sec @ 74μs/op
|
||||
├─cbc-256 x 13,664 ops/sec @ 73μs/op
|
||||
└─ecb-256 x 22,426 ops/sec @ 44μs/op
|
||||
encrypt (1MB)
|
||||
├─ctr-256 x 106 ops/sec @ 9ms/op
|
||||
├─cbc-256 x 109 ops/sec @ 9ms/op
|
||||
└─ecb-256 x 179 ops/sec @ 5ms/op
|
||||
```
|
||||
|
||||
Compare to other implementations:
|
||||
|
||||
```
|
||||
xsalsa20poly1305 (encrypt, 1MB)
|
||||
├─tweetnacl x 108 ops/sec @ 9ms/op
|
||||
└─noble x 190 ops/sec @ 5ms/op
|
||||
|
||||
chacha20poly1305 (encrypt, 1MB)
|
||||
├─node x 1,360 ops/sec @ 735μs/op
|
||||
├─stablelib x 117 ops/sec @ 8ms/op
|
||||
└─noble x 193 ops/sec @ 5ms/op
|
||||
|
||||
chacha (encrypt, 1MB)
|
||||
├─node x 2,035 ops/sec @ 491μs/op
|
||||
├─stablelib x 206 ops/sec @ 4ms/op
|
||||
└─noble x 474 ops/sec @ 2ms/op
|
||||
|
||||
ctr-256 (encrypt, 1MB)
|
||||
├─node x 3,530 ops/sec @ 283μs/op
|
||||
├─stablelib x 70 ops/sec @ 14ms/op
|
||||
├─aesjs x 31 ops/sec @ 32ms/op
|
||||
├─noble-webcrypto x 4,589 ops/sec @ 217μs/op
|
||||
└─noble x 107 ops/sec @ 9ms/op
|
||||
|
||||
cbc-256 (encrypt, 1MB)
|
||||
├─node x 993 ops/sec @ 1ms/op
|
||||
├─stablelib x 63 ops/sec @ 15ms/op
|
||||
├─aesjs x 29 ops/sec @ 34ms/op
|
||||
├─noble-webcrypto x 1,087 ops/sec @ 919μs/op
|
||||
└─noble x 110 ops/sec @ 9ms/op
|
||||
|
||||
gcm-256 (encrypt, 1MB)
|
||||
├─node x 3,196 ops/sec @ 312μs/op
|
||||
├─stablelib x 27 ops/sec @ 36ms/op
|
||||
├─noble-webcrypto x 4,059 ops/sec @ 246μs/op
|
||||
└─noble x 74 ops/sec @ 13ms/op
|
||||
```
|
||||
|
||||
## Upgrading
|
||||
|
||||
Upgrade from `micro-aes-gcm` package is simple:
|
||||
|
||||
```js
|
||||
// prepare
|
||||
const key = Uint8Array.from([
|
||||
64, 196, 127, 247, 172, 2, 34, 159, 6, 241, 30, 174, 183, 229, 41, 114, 253, 122, 119, 168, 177,
|
||||
243, 155, 236, 164, 159, 98, 72, 162, 243, 224, 195,
|
||||
]);
|
||||
const message = 'Hello world';
|
||||
|
||||
// previous
|
||||
import * as aes from 'micro-aes-gcm';
|
||||
const ciphertext = await aes.encrypt(key, aes.utils.utf8ToBytes(message));
|
||||
const plaintext = await aes.decrypt(key, ciphertext);
|
||||
console.log(aes.utils.bytesToUtf8(plaintext) === message);
|
||||
|
||||
// became =>
|
||||
|
||||
import { gcm } from '@noble/ciphers/aes';
|
||||
import { bytesToUtf8, utf8ToBytes } from '@noble/ciphers/utils';
|
||||
import { managedNonce } from '@noble/ciphers/webcrypto';
|
||||
const aes = managedNonce(gcm)(key);
|
||||
const ciphertext = aes.encrypt(utf8ToBytes(message));
|
||||
const plaintext = aes.decrypt(key, ciphertext);
|
||||
console.log(bytesToUtf8(plaintext) === message);
|
||||
```
|
||||
|
||||
## Contributing & testing
|
||||
|
||||
1. Clone the repository
|
||||
2. `npm install` to install build dependencies like TypeScript
|
||||
3. `npm run build` to compile TypeScript code
|
||||
4. `npm run test` will execute all main tests
|
||||
|
||||
## Resources
|
||||
|
||||
Check out [paulmillr.com/noble](https://paulmillr.com/noble/)
|
||||
for useful resources, articles, documentation and demos
|
||||
related to the library.
|
||||
|
||||
## License
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2023 Paul Miller [(https://paulmillr.com)](https://paulmillr.com)
|
||||
Copyright (c) 2016 Thomas Pornin <pornin@bolet.org>
|
||||
|
||||
See LICENSE file.
|
||||
14
thrower_daemon/node_modules/@noble/ciphers/_arx.d.ts
generated
vendored
Normal file
14
thrower_daemon/node_modules/@noble/ciphers/_arx.d.ts
generated
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
import { XorStream } from './utils.js';
|
||||
export declare const sigma: Uint32Array;
|
||||
export declare function rotl(a: number, b: number): number;
|
||||
export type CipherCoreFn = (sigma: Uint32Array, key: Uint32Array, nonce: Uint32Array, output: Uint32Array, counter: number, rounds?: number) => void;
|
||||
export type ExtendNonceFn = (sigma: Uint32Array, key: Uint32Array, input: Uint32Array, output: Uint32Array) => void;
|
||||
export type CipherOpts = {
|
||||
allowShortKeys?: boolean;
|
||||
extendNonceFn?: ExtendNonceFn;
|
||||
counterLength?: number;
|
||||
counterRight?: boolean;
|
||||
rounds?: number;
|
||||
};
|
||||
export declare function createCipher(core: CipherCoreFn, opts: CipherOpts): XorStream;
|
||||
//# sourceMappingURL=_arx.d.ts.map
|
||||
1
thrower_daemon/node_modules/@noble/ciphers/_arx.d.ts.map
generated
vendored
Normal file
1
thrower_daemon/node_modules/@noble/ciphers/_arx.d.ts.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"_arx.d.ts","sourceRoot":"","sources":["src/_arx.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,SAAS,EAAkB,MAAM,YAAY,CAAC;AA4CvD,eAAO,MAAM,KAAK,aAAqB,CAAC;AAExC,wBAAgB,IAAI,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAEjD;AAED,MAAM,MAAM,YAAY,GAAG,CACzB,KAAK,EAAE,WAAW,EAClB,GAAG,EAAE,WAAW,EAChB,KAAK,EAAE,WAAW,EAClB,MAAM,EAAE,WAAW,EACnB,OAAO,EAAE,MAAM,EACf,MAAM,CAAC,EAAE,MAAM,KACZ,IAAI,CAAC;AAEV,MAAM,MAAM,aAAa,GAAG,CAC1B,KAAK,EAAE,WAAW,EAClB,GAAG,EAAE,WAAW,EAChB,KAAK,EAAE,WAAW,EAClB,MAAM,EAAE,WAAW,KAChB,IAAI,CAAC;AAEV,MAAM,MAAM,UAAU,GAAG;IACvB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,CAAC;AAwDF,wBAAgB,YAAY,CAAC,IAAI,EAAE,YAAY,EAAE,IAAI,EAAE,UAAU,GAAG,SAAS,CAsF5E"}
|
||||
175
thrower_daemon/node_modules/@noble/ciphers/_arx.js
generated
vendored
Normal file
175
thrower_daemon/node_modules/@noble/ciphers/_arx.js
generated
vendored
Normal file
@@ -0,0 +1,175 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.createCipher = exports.rotl = exports.sigma = void 0;
|
||||
// Basic utils for ARX (add-rotate-xor) salsa and chacha ciphers.
|
||||
const _assert_js_1 = require("./_assert.js");
|
||||
const utils_js_1 = require("./utils.js");
|
||||
/*
|
||||
RFC8439 requires multi-step cipher stream, where
|
||||
authKey starts with counter: 0, actual msg with counter: 1.
|
||||
|
||||
For this, we need a way to re-use nonce / counter:
|
||||
|
||||
const counter = new Uint8Array(4);
|
||||
chacha(..., counter, ...); // counter is now 1
|
||||
chacha(..., counter, ...); // counter is now 2
|
||||
|
||||
This is complicated:
|
||||
|
||||
- 32-bit counters are enough, no need for 64-bit: max ArrayBuffer size in JS is 4GB
|
||||
- Original papers don't allow mutating counters
|
||||
- Counter overflow is undefined [^1]
|
||||
- Idea A: allow providing (nonce | counter) instead of just nonce, re-use it
|
||||
- Caveat: Cannot be re-used through all cases:
|
||||
- * chacha has (counter | nonce)
|
||||
- * xchacha has (nonce16 | counter | nonce16)
|
||||
- Idea B: separate nonce / counter and provide separate API for counter re-use
|
||||
- Caveat: there are different counter sizes depending on an algorithm.
|
||||
- salsa & chacha also differ in structures of key & sigma:
|
||||
salsa20: s[0] | k(4) | s[1] | nonce(2) | ctr(2) | s[2] | k(4) | s[3]
|
||||
chacha: s(4) | k(8) | ctr(1) | nonce(3)
|
||||
chacha20orig: s(4) | k(8) | ctr(2) | nonce(2)
|
||||
- Idea C: helper method such as `setSalsaState(key, nonce, sigma, data)`
|
||||
- Caveat: we can't re-use counter array
|
||||
|
||||
xchacha [^2] uses the subkey and remaining 8 byte nonce with ChaCha20 as normal
|
||||
(prefixed by 4 NUL bytes, since [RFC8439] specifies a 12-byte nonce).
|
||||
|
||||
[^1]: https://mailarchive.ietf.org/arch/msg/cfrg/gsOnTJzcbgG6OqD8Sc0GO5aR_tU/
|
||||
[^2]: https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-xchacha#appendix-A.2
|
||||
*/
|
||||
// We can't make top-level var depend on utils.utf8ToBytes
|
||||
// because it's not present in all envs. Creating a similar fn here
|
||||
const _utf8ToBytes = (str) => Uint8Array.from(str.split('').map((c) => c.charCodeAt(0)));
|
||||
const sigma16 = _utf8ToBytes('expand 16-byte k');
|
||||
const sigma32 = _utf8ToBytes('expand 32-byte k');
|
||||
const sigma16_32 = (0, utils_js_1.u32)(sigma16);
|
||||
const sigma32_32 = (0, utils_js_1.u32)(sigma32);
|
||||
exports.sigma = sigma32_32.slice();
|
||||
function rotl(a, b) {
|
||||
return (a << b) | (a >>> (32 - b));
|
||||
}
|
||||
exports.rotl = rotl;
|
||||
// Is byte array aligned to 4 byte offset (u32)?
|
||||
function isAligned32(b) {
|
||||
return b.byteOffset % 4 === 0;
|
||||
}
|
||||
// Salsa and Chacha block length is always 512-bit
|
||||
const BLOCK_LEN = 64;
|
||||
const BLOCK_LEN32 = 16;
|
||||
// new Uint32Array([2**32]) // => Uint32Array(1) [ 0 ]
|
||||
// new Uint32Array([2**32-1]) // => Uint32Array(1) [ 4294967295 ]
|
||||
const MAX_COUNTER = 2 ** 32 - 1;
|
||||
const U32_EMPTY = new Uint32Array();
|
||||
function runCipher(core, sigma, key, nonce, data, output, counter, rounds) {
|
||||
const len = data.length;
|
||||
const block = new Uint8Array(BLOCK_LEN);
|
||||
const b32 = (0, utils_js_1.u32)(block);
|
||||
// Make sure that buffers aligned to 4 bytes
|
||||
const isAligned = isAligned32(data) && isAligned32(output);
|
||||
const d32 = isAligned ? (0, utils_js_1.u32)(data) : U32_EMPTY;
|
||||
const o32 = isAligned ? (0, utils_js_1.u32)(output) : U32_EMPTY;
|
||||
for (let pos = 0; pos < len; counter++) {
|
||||
core(sigma, key, nonce, b32, counter, rounds);
|
||||
if (counter >= MAX_COUNTER)
|
||||
throw new Error('arx: counter overflow');
|
||||
const take = Math.min(BLOCK_LEN, len - pos);
|
||||
// aligned to 4 bytes
|
||||
if (isAligned && take === BLOCK_LEN) {
|
||||
const pos32 = pos / 4;
|
||||
if (pos % 4 !== 0)
|
||||
throw new Error('arx: invalid block position');
|
||||
for (let j = 0, posj; j < BLOCK_LEN32; j++) {
|
||||
posj = pos32 + j;
|
||||
o32[posj] = d32[posj] ^ b32[j];
|
||||
}
|
||||
pos += BLOCK_LEN;
|
||||
continue;
|
||||
}
|
||||
for (let j = 0, posj; j < take; j++) {
|
||||
posj = pos + j;
|
||||
output[posj] = data[posj] ^ block[j];
|
||||
}
|
||||
pos += take;
|
||||
}
|
||||
}
|
||||
function createCipher(core, opts) {
|
||||
const { allowShortKeys, extendNonceFn, counterLength, counterRight, rounds } = (0, utils_js_1.checkOpts)({ allowShortKeys: false, counterLength: 8, counterRight: false, rounds: 20 }, opts);
|
||||
if (typeof core !== 'function')
|
||||
throw new Error('core must be a function');
|
||||
(0, _assert_js_1.number)(counterLength);
|
||||
(0, _assert_js_1.number)(rounds);
|
||||
(0, _assert_js_1.bool)(counterRight);
|
||||
(0, _assert_js_1.bool)(allowShortKeys);
|
||||
return (key, nonce, data, output, counter = 0) => {
|
||||
(0, _assert_js_1.bytes)(key);
|
||||
(0, _assert_js_1.bytes)(nonce);
|
||||
(0, _assert_js_1.bytes)(data);
|
||||
const len = data.length;
|
||||
if (!output)
|
||||
output = new Uint8Array(len);
|
||||
(0, _assert_js_1.bytes)(output);
|
||||
(0, _assert_js_1.number)(counter);
|
||||
if (counter < 0 || counter >= MAX_COUNTER)
|
||||
throw new Error('arx: counter overflow');
|
||||
if (output.length < len)
|
||||
throw new Error(`arx: output (${output.length}) is shorter than data (${len})`);
|
||||
const toClean = [];
|
||||
// Key & sigma
|
||||
// key=16 -> sigma16, k=key|key
|
||||
// key=32 -> sigma32, k=key
|
||||
let l = key.length, k, sigma;
|
||||
if (l === 32) {
|
||||
k = key.slice();
|
||||
toClean.push(k);
|
||||
sigma = sigma32_32;
|
||||
}
|
||||
else if (l === 16 && allowShortKeys) {
|
||||
k = new Uint8Array(32);
|
||||
k.set(key);
|
||||
k.set(key, 16);
|
||||
sigma = sigma16_32;
|
||||
toClean.push(k);
|
||||
}
|
||||
else {
|
||||
throw new Error(`arx: invalid 32-byte key, got length=${l}`);
|
||||
}
|
||||
// Nonce
|
||||
// salsa20: 8 (8-byte counter)
|
||||
// chacha20orig: 8 (8-byte counter)
|
||||
// chacha20: 12 (4-byte counter)
|
||||
// xsalsa20: 24 (16 -> hsalsa, 8 -> old nonce)
|
||||
// xchacha20: 24 (16 -> hchacha, 8 -> old nonce)
|
||||
// Align nonce to 4 bytes
|
||||
if (!isAligned32(nonce)) {
|
||||
nonce = nonce.slice();
|
||||
toClean.push(nonce);
|
||||
}
|
||||
const k32 = (0, utils_js_1.u32)(k);
|
||||
// hsalsa & hchacha: handle extended nonce
|
||||
if (extendNonceFn) {
|
||||
if (nonce.length !== 24)
|
||||
throw new Error(`arx: extended nonce must be 24 bytes`);
|
||||
extendNonceFn(sigma, k32, (0, utils_js_1.u32)(nonce.subarray(0, 16)), k32);
|
||||
nonce = nonce.subarray(16);
|
||||
}
|
||||
// Handle nonce counter
|
||||
const nonceNcLen = 16 - counterLength;
|
||||
if (nonceNcLen !== nonce.length)
|
||||
throw new Error(`arx: nonce must be ${nonceNcLen} or 16 bytes`);
|
||||
// Pad counter when nonce is 64 bit
|
||||
if (nonceNcLen !== 12) {
|
||||
const nc = new Uint8Array(12);
|
||||
nc.set(nonce, counterRight ? 0 : 12 - nonce.length);
|
||||
nonce = nc;
|
||||
toClean.push(nonce);
|
||||
}
|
||||
const n32 = (0, utils_js_1.u32)(nonce);
|
||||
runCipher(core, sigma, k32, n32, data, output, counter, rounds);
|
||||
while (toClean.length > 0)
|
||||
toClean.pop().fill(0);
|
||||
return output;
|
||||
};
|
||||
}
|
||||
exports.createCipher = createCipher;
|
||||
//# sourceMappingURL=_arx.js.map
|
||||
1
thrower_daemon/node_modules/@noble/ciphers/_arx.js.map
generated
vendored
Normal file
1
thrower_daemon/node_modules/@noble/ciphers/_arx.js.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
24
thrower_daemon/node_modules/@noble/ciphers/_assert.d.ts
generated
vendored
Normal file
24
thrower_daemon/node_modules/@noble/ciphers/_assert.d.ts
generated
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
declare function number(n: number): void;
|
||||
declare function bool(b: boolean): void;
|
||||
export declare function isBytes(a: unknown): a is Uint8Array;
|
||||
declare function bytes(b: Uint8Array | undefined, ...lengths: number[]): void;
|
||||
export type Hash = {
|
||||
(data: Uint8Array): Uint8Array;
|
||||
blockLen: number;
|
||||
outputLen: number;
|
||||
create: any;
|
||||
};
|
||||
declare function hash(hash: Hash): void;
|
||||
declare function exists(instance: any, checkFinished?: boolean): void;
|
||||
declare function output(out: any, instance: any): void;
|
||||
export { number, bool, bytes, hash, exists, output };
|
||||
declare const assert: {
|
||||
number: typeof number;
|
||||
bool: typeof bool;
|
||||
bytes: typeof bytes;
|
||||
hash: typeof hash;
|
||||
exists: typeof exists;
|
||||
output: typeof output;
|
||||
};
|
||||
export default assert;
|
||||
//# sourceMappingURL=_assert.d.ts.map
|
||||
1
thrower_daemon/node_modules/@noble/ciphers/_assert.d.ts.map
generated
vendored
Normal file
1
thrower_daemon/node_modules/@noble/ciphers/_assert.d.ts.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"_assert.d.ts","sourceRoot":"","sources":["src/_assert.ts"],"names":[],"mappings":"AAAA,iBAAS,MAAM,CAAC,CAAC,EAAE,MAAM,QAExB;AAED,iBAAS,IAAI,CAAC,CAAC,EAAE,OAAO,QAEvB;AAED,wBAAgB,OAAO,CAAC,CAAC,EAAE,OAAO,GAAG,CAAC,IAAI,UAAU,CAKnD;AAED,iBAAS,KAAK,CAAC,CAAC,EAAE,UAAU,GAAG,SAAS,EAAE,GAAG,OAAO,EAAE,MAAM,EAAE,QAI7D;AAED,MAAM,MAAM,IAAI,GAAG;IACjB,CAAC,IAAI,EAAE,UAAU,GAAG,UAAU,CAAC;IAC/B,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,GAAG,CAAC;CACb,CAAC;AACF,iBAAS,IAAI,CAAC,IAAI,EAAE,IAAI,QAKvB;AAED,iBAAS,MAAM,CAAC,QAAQ,EAAE,GAAG,EAAE,aAAa,UAAO,QAGlD;AAED,iBAAS,MAAM,CAAC,GAAG,EAAE,GAAG,EAAE,QAAQ,EAAE,GAAG,QAMtC;AAED,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC;AACrD,QAAA,MAAM,MAAM;;;;;;;CAAgD,CAAC;AAC7D,eAAe,MAAM,CAAC"}
|
||||
50
thrower_daemon/node_modules/@noble/ciphers/_assert.js
generated
vendored
Normal file
50
thrower_daemon/node_modules/@noble/ciphers/_assert.js
generated
vendored
Normal file
@@ -0,0 +1,50 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.output = exports.exists = exports.hash = exports.bytes = exports.bool = exports.number = exports.isBytes = void 0;
|
||||
function number(n) {
|
||||
if (!Number.isSafeInteger(n) || n < 0)
|
||||
throw new Error(`positive integer expected, not ${n}`);
|
||||
}
|
||||
exports.number = number;
|
||||
function bool(b) {
|
||||
if (typeof b !== 'boolean')
|
||||
throw new Error(`boolean expected, not ${b}`);
|
||||
}
|
||||
exports.bool = bool;
|
||||
function isBytes(a) {
|
||||
return (a instanceof Uint8Array ||
|
||||
(a != null && typeof a === 'object' && a.constructor.name === 'Uint8Array'));
|
||||
}
|
||||
exports.isBytes = isBytes;
|
||||
function bytes(b, ...lengths) {
|
||||
if (!isBytes(b))
|
||||
throw new Error('Uint8Array expected');
|
||||
if (lengths.length > 0 && !lengths.includes(b.length))
|
||||
throw new Error(`Uint8Array expected of length ${lengths}, not of length=${b.length}`);
|
||||
}
|
||||
exports.bytes = bytes;
|
||||
function hash(hash) {
|
||||
if (typeof hash !== 'function' || typeof hash.create !== 'function')
|
||||
throw new Error('hash must be wrapped by utils.wrapConstructor');
|
||||
number(hash.outputLen);
|
||||
number(hash.blockLen);
|
||||
}
|
||||
exports.hash = hash;
|
||||
function exists(instance, checkFinished = true) {
|
||||
if (instance.destroyed)
|
||||
throw new Error('Hash instance has been destroyed');
|
||||
if (checkFinished && instance.finished)
|
||||
throw new Error('Hash#digest() has already been called');
|
||||
}
|
||||
exports.exists = exists;
|
||||
function output(out, instance) {
|
||||
bytes(out);
|
||||
const min = instance.outputLen;
|
||||
if (out.length < min) {
|
||||
throw new Error(`digestInto() expects output buffer of length at least ${min}`);
|
||||
}
|
||||
}
|
||||
exports.output = output;
|
||||
const assert = { number, bool, bytes, hash, exists, output };
|
||||
exports.default = assert;
|
||||
//# sourceMappingURL=_assert.js.map
|
||||
1
thrower_daemon/node_modules/@noble/ciphers/_assert.js.map
generated
vendored
Normal file
1
thrower_daemon/node_modules/@noble/ciphers/_assert.js.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"_assert.js","sourceRoot":"","sources":["src/_assert.ts"],"names":[],"mappings":";;;AAAA,SAAS,MAAM,CAAC,CAAS;IACvB,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,kCAAkC,CAAC,EAAE,CAAC,CAAC;AAChG,CAAC;AA6CQ,wBAAM;AA3Cf,SAAS,IAAI,CAAC,CAAU;IACtB,IAAI,OAAO,CAAC,KAAK,SAAS;QAAE,MAAM,IAAI,KAAK,CAAC,yBAAyB,CAAC,EAAE,CAAC,CAAC;AAC5E,CAAC;AAyCgB,oBAAI;AAvCrB,SAAgB,OAAO,CAAC,CAAU;IAChC,OAAO,CACL,CAAC,YAAY,UAAU;QACvB,CAAC,CAAC,IAAI,IAAI,IAAI,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,CAAC,WAAW,CAAC,IAAI,KAAK,YAAY,CAAC,CAC5E,CAAC;AACJ,CAAC;AALD,0BAKC;AAED,SAAS,KAAK,CAAC,CAAyB,EAAE,GAAG,OAAiB;IAC5D,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,qBAAqB,CAAC,CAAC;IACxD,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC;QACnD,MAAM,IAAI,KAAK,CAAC,iCAAiC,OAAO,mBAAmB,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC;AAC3F,CAAC;AA4BsB,sBAAK;AApB5B,SAAS,IAAI,CAAC,IAAU;IACtB,IAAI,OAAO,IAAI,KAAK,UAAU,IAAI,OAAO,IAAI,CAAC,MAAM,KAAK,UAAU;QACjE,MAAM,IAAI,KAAK,CAAC,+CAA+C,CAAC,CAAC;IACnE,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IACvB,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;AACxB,CAAC;AAe6B,oBAAI;AAblC,SAAS,MAAM,CAAC,QAAa,EAAE,aAAa,GAAG,IAAI;IACjD,IAAI,QAAQ,CAAC,SAAS;QAAE,MAAM,IAAI,KAAK,CAAC,kCAAkC,CAAC,CAAC;IAC5E,IAAI,aAAa,IAAI,QAAQ,CAAC,QAAQ;QAAE,MAAM,IAAI,KAAK,CAAC,uCAAuC,CAAC,CAAC;AACnG,CAAC;AAUmC,wBAAM;AAR1C,SAAS,MAAM,CAAC,GAAQ,EAAE,QAAa;IACrC,KAAK,CAAC,GAAG,CAAC,CAAC;IACX,MAAM,GAAG,GAAG,QAAQ,CAAC,SAAS,CAAC;IAC/B,IAAI,GAAG,CAAC,MAAM,GAAG,GAAG,EAAE,CAAC;QACrB,MAAM,IAAI,KAAK,CAAC,yDAAyD,GAAG,EAAE,CAAC,CAAC;IAClF,CAAC;AACH,CAAC;AAE2C,wBAAM;AAClD,MAAM,MAAM,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC;AAC7D,kBAAe,MAAM,CAAC"}
|
||||
70
thrower_daemon/node_modules/@noble/ciphers/_micro.d.ts
generated
vendored
Normal file
70
thrower_daemon/node_modules/@noble/ciphers/_micro.d.ts
generated
vendored
Normal file
@@ -0,0 +1,70 @@
|
||||
/*! noble-ciphers - MIT License (c) 2023 Paul Miller (paulmillr.com) */
|
||||
import { Cipher, XorStream } from './utils.js';
|
||||
export declare function hsalsa(s: Uint32Array, k: Uint32Array, i: Uint32Array, o32: Uint32Array): void;
|
||||
export declare function hchacha(s: Uint32Array, k: Uint32Array, i: Uint32Array, o32: Uint32Array): void;
|
||||
/**
|
||||
* salsa20, 12-byte nonce.
|
||||
*/
|
||||
export declare const salsa20: XorStream;
|
||||
/**
|
||||
* xsalsa20, 24-byte nonce.
|
||||
*/
|
||||
export declare const xsalsa20: XorStream;
|
||||
/**
|
||||
* chacha20 non-RFC, original version by djb. 8-byte nonce, 8-byte counter.
|
||||
*/
|
||||
export declare const chacha20orig: XorStream;
|
||||
/**
|
||||
* chacha20 RFC 8439 (IETF / TLS). 12-byte nonce, 4-byte counter.
|
||||
*/
|
||||
export declare const chacha20: XorStream;
|
||||
/**
|
||||
* xchacha20 eXtended-nonce. https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-xchacha
|
||||
*/
|
||||
export declare const xchacha20: XorStream;
|
||||
/**
|
||||
* 8-round chacha from the original paper.
|
||||
*/
|
||||
export declare const chacha8: XorStream;
|
||||
/**
|
||||
* 12-round chacha from the original paper.
|
||||
*/
|
||||
export declare const chacha12: XorStream;
|
||||
export declare function poly1305(msg: Uint8Array, key: Uint8Array): Uint8Array;
|
||||
/**
|
||||
* xsalsa20-poly1305 eXtended-nonce (24 bytes) salsa.
|
||||
*/
|
||||
export declare const xsalsa20poly1305: ((key: Uint8Array, nonce: Uint8Array) => {
|
||||
encrypt: (plaintext: Uint8Array) => Uint8Array;
|
||||
decrypt: (ciphertext: Uint8Array) => Uint8Array;
|
||||
}) & {
|
||||
blockSize: number;
|
||||
nonceLength: number;
|
||||
tagLength: number;
|
||||
};
|
||||
/**
|
||||
* Alias to xsalsa20-poly1305
|
||||
*/
|
||||
export declare function secretbox(key: Uint8Array, nonce: Uint8Array): {
|
||||
seal: (plaintext: Uint8Array) => Uint8Array;
|
||||
open: (ciphertext: Uint8Array) => Uint8Array;
|
||||
};
|
||||
export declare const _poly1305_aead: (fn: XorStream) => (key: Uint8Array, nonce: Uint8Array, AAD?: Uint8Array) => Cipher;
|
||||
/**
|
||||
* chacha20-poly1305 12-byte-nonce chacha.
|
||||
*/
|
||||
export declare const chacha20poly1305: ((key: Uint8Array, nonce: Uint8Array, AAD?: Uint8Array) => Cipher) & {
|
||||
blockSize: number;
|
||||
nonceLength: number;
|
||||
tagLength: number;
|
||||
};
|
||||
/**
|
||||
* xchacha20-poly1305 eXtended-nonce (24 bytes) chacha.
|
||||
* With 24-byte nonce, it's safe to use fill it with random (CSPRNG).
|
||||
*/
|
||||
export declare const xchacha20poly1305: ((key: Uint8Array, nonce: Uint8Array, AAD?: Uint8Array) => Cipher) & {
|
||||
blockSize: number;
|
||||
nonceLength: number;
|
||||
tagLength: number;
|
||||
};
|
||||
//# sourceMappingURL=_micro.d.ts.map
|
||||
1
thrower_daemon/node_modules/@noble/ciphers/_micro.d.ts.map
generated
vendored
Normal file
1
thrower_daemon/node_modules/@noble/ciphers/_micro.d.ts.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"_micro.d.ts","sourceRoot":"","sources":["src/_micro.ts"],"names":[],"mappings":"AAAA,uEAAuE;AAEvE,OAAO,EACL,MAAM,EAAE,SAAS,EAElB,MAAM,YAAY,CAAC;AA+EpB,wBAAgB,MAAM,CAAC,CAAC,EAAE,WAAW,EAAE,CAAC,EAAE,WAAW,EAAE,CAAC,EAAE,WAAW,EAAE,GAAG,EAAE,WAAW,QAatF;AAuBD,wBAAgB,OAAO,CAAC,CAAC,EAAE,WAAW,EAAE,CAAC,EAAE,WAAW,EAAE,CAAC,EAAE,WAAW,EAAE,GAAG,EAAE,WAAW,QAavF;AAED;;GAEG;AACH,eAAO,MAAM,OAAO,WAGlB,CAAC;AAEH;;GAEG;AACH,eAAO,MAAM,QAAQ,WAGnB,CAAC;AAEH;;GAEG;AACH,eAAO,MAAM,YAAY,WAIvB,CAAC;AAEH;;GAEG;AACH,eAAO,MAAM,QAAQ,WAGnB,CAAC;AAEH;;GAEG;AACH,eAAO,MAAM,SAAS,WAIpB,CAAC;AAEH;;GAEG;AACH,eAAO,MAAM,OAAO,WAIlB,CAAC;AAEH;;GAEG;AACH,eAAO,MAAM,QAAQ,WAInB,CAAC;AAQH,wBAAgB,QAAQ,CAAC,GAAG,EAAE,UAAU,EAAE,GAAG,EAAE,UAAU,GAAG,UAAU,CAcrE;AA4BD;;GAEG;AACH,eAAO,MAAM,gBAAgB,SAEI,UAAU,SAAS,UAAU;yBAInC,UAAU;0BAST,UAAU;;;;;CAWrC,CAAC;AAEF;;GAEG;AACH,wBAAgB,SAAS,CAAC,GAAG,EAAE,UAAU,EAAE,KAAK,EAAE,UAAU;;;EAG3D;AAED,eAAO,MAAM,cAAc,OACpB,SAAS,WACR,UAAU,SAAS,UAAU,QAAQ,UAAU,KAAG,MAuBvD,CAAC;AAEJ;;GAEG;AACH,eAAO,MAAM,gBAAgB,SA5BrB,UAAU,SAAS,UAAU,QAAQ,UAAU,KAAG,MAAM;;;;CA+B/D,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,iBAAiB,SArCtB,UAAU,SAAS,UAAU,QAAQ,UAAU,KAAG,MAAM;;;;CAwC/D,CAAC"}
|
||||
295
thrower_daemon/node_modules/@noble/ciphers/_micro.js
generated
vendored
Normal file
295
thrower_daemon/node_modules/@noble/ciphers/_micro.js
generated
vendored
Normal file
@@ -0,0 +1,295 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.xchacha20poly1305 = exports.chacha20poly1305 = exports._poly1305_aead = exports.secretbox = exports.xsalsa20poly1305 = exports.poly1305 = exports.chacha12 = exports.chacha8 = exports.xchacha20 = exports.chacha20 = exports.chacha20orig = exports.xsalsa20 = exports.salsa20 = exports.hchacha = exports.hsalsa = void 0;
|
||||
/*! noble-ciphers - MIT License (c) 2023 Paul Miller (paulmillr.com) */
|
||||
// prettier-ignore
|
||||
const utils_js_1 = require("./utils.js");
|
||||
const _arx_js_1 = require("./_arx.js");
|
||||
const _assert_js_1 = require("./_assert.js");
|
||||
/*
|
||||
noble-ciphers-micro: more auditable, but slower version of salsa20, chacha & poly1305.
|
||||
Implements the same algorithms that are present in other files, but without
|
||||
unrolled loops (https://en.wikipedia.org/wiki/Loop_unrolling).
|
||||
*/
|
||||
function bytesToNumberLE(bytes) {
|
||||
return (0, utils_js_1.hexToNumber)((0, utils_js_1.bytesToHex)(Uint8Array.from(bytes).reverse()));
|
||||
}
|
||||
function numberToBytesLE(n, len) {
|
||||
return (0, utils_js_1.numberToBytesBE)(n, len).reverse();
|
||||
}
|
||||
function salsaQR(x, a, b, c, d) {
|
||||
x[b] ^= (0, _arx_js_1.rotl)((x[a] + x[d]) | 0, 7);
|
||||
x[c] ^= (0, _arx_js_1.rotl)((x[b] + x[a]) | 0, 9);
|
||||
x[d] ^= (0, _arx_js_1.rotl)((x[c] + x[b]) | 0, 13);
|
||||
x[a] ^= (0, _arx_js_1.rotl)((x[d] + x[c]) | 0, 18);
|
||||
}
|
||||
// prettier-ignore
|
||||
function chachaQR(x, a, b, c, d) {
|
||||
x[a] = (x[a] + x[b]) | 0;
|
||||
x[d] = (0, _arx_js_1.rotl)(x[d] ^ x[a], 16);
|
||||
x[c] = (x[c] + x[d]) | 0;
|
||||
x[b] = (0, _arx_js_1.rotl)(x[b] ^ x[c], 12);
|
||||
x[a] = (x[a] + x[b]) | 0;
|
||||
x[d] = (0, _arx_js_1.rotl)(x[d] ^ x[a], 8);
|
||||
x[c] = (x[c] + x[d]) | 0;
|
||||
x[b] = (0, _arx_js_1.rotl)(x[b] ^ x[c], 7);
|
||||
}
|
||||
function salsaRound(x, rounds = 20) {
|
||||
for (let r = 0; r < rounds; r += 2) {
|
||||
salsaQR(x, 0, 4, 8, 12);
|
||||
salsaQR(x, 5, 9, 13, 1);
|
||||
salsaQR(x, 10, 14, 2, 6);
|
||||
salsaQR(x, 15, 3, 7, 11);
|
||||
salsaQR(x, 0, 1, 2, 3);
|
||||
salsaQR(x, 5, 6, 7, 4);
|
||||
salsaQR(x, 10, 11, 8, 9);
|
||||
salsaQR(x, 15, 12, 13, 14);
|
||||
}
|
||||
}
|
||||
function chachaRound(x, rounds = 20) {
|
||||
for (let r = 0; r < rounds; r += 2) {
|
||||
chachaQR(x, 0, 4, 8, 12);
|
||||
chachaQR(x, 1, 5, 9, 13);
|
||||
chachaQR(x, 2, 6, 10, 14);
|
||||
chachaQR(x, 3, 7, 11, 15);
|
||||
chachaQR(x, 0, 5, 10, 15);
|
||||
chachaQR(x, 1, 6, 11, 12);
|
||||
chachaQR(x, 2, 7, 8, 13);
|
||||
chachaQR(x, 3, 4, 9, 14);
|
||||
}
|
||||
}
|
||||
function salsaCore(s, k, n, out, cnt, rounds = 20) {
|
||||
// prettier-ignore
|
||||
const y = new Uint32Array([
|
||||
s[0], k[0], k[1], k[2], // "expa" Key Key Key
|
||||
k[3], s[1], n[0], n[1], // Key "nd 3" Nonce Nonce
|
||||
cnt, 0, s[2], k[4], // Pos. Pos. "2-by" Key
|
||||
k[5], k[6], k[7], s[3], // Key Key Key "te k"
|
||||
]);
|
||||
const x = y.slice();
|
||||
salsaRound(x, rounds);
|
||||
for (let i = 0; i < 16; i++)
|
||||
out[i] = (y[i] + x[i]) | 0;
|
||||
}
|
||||
// prettier-ignore
|
||||
function hsalsa(s, k, i, o32) {
|
||||
const x = new Uint32Array([
|
||||
s[0], k[0], k[1], k[2],
|
||||
k[3], s[1], i[0], i[1],
|
||||
i[2], i[3], s[2], k[4],
|
||||
k[5], k[6], k[7], s[3]
|
||||
]);
|
||||
salsaRound(x, 20);
|
||||
let oi = 0;
|
||||
o32[oi++] = x[0];
|
||||
o32[oi++] = x[5];
|
||||
o32[oi++] = x[10];
|
||||
o32[oi++] = x[15];
|
||||
o32[oi++] = x[6];
|
||||
o32[oi++] = x[7];
|
||||
o32[oi++] = x[8];
|
||||
o32[oi++] = x[9];
|
||||
}
|
||||
exports.hsalsa = hsalsa;
|
||||
function chachaCore(s, k, n, out, cnt, rounds = 20) {
|
||||
// prettier-ignore
|
||||
const y = new Uint32Array([
|
||||
s[0], s[1], s[2], s[3], // "expa" "nd 3" "2-by" "te k"
|
||||
k[0], k[1], k[2], k[3], // Key Key Key Key
|
||||
k[4], k[5], k[6], k[7], // Key Key Key Key
|
||||
cnt, n[0], n[1], n[2], // Counter Counter Nonce Nonce
|
||||
]);
|
||||
const x = y.slice();
|
||||
chachaRound(x, rounds);
|
||||
for (let i = 0; i < 16; i++)
|
||||
out[i] = (y[i] + x[i]) | 0;
|
||||
}
|
||||
// prettier-ignore
|
||||
function hchacha(s, k, i, o32) {
|
||||
const x = new Uint32Array([
|
||||
s[0], s[1], s[2], s[3],
|
||||
k[0], k[1], k[2], k[3],
|
||||
k[4], k[5], k[6], k[7],
|
||||
i[0], i[1], i[2], i[3],
|
||||
]);
|
||||
chachaRound(x, 20);
|
||||
let oi = 0;
|
||||
o32[oi++] = x[0];
|
||||
o32[oi++] = x[1];
|
||||
o32[oi++] = x[2];
|
||||
o32[oi++] = x[3];
|
||||
o32[oi++] = x[12];
|
||||
o32[oi++] = x[13];
|
||||
o32[oi++] = x[14];
|
||||
o32[oi++] = x[15];
|
||||
}
|
||||
exports.hchacha = hchacha;
|
||||
/**
|
||||
* salsa20, 12-byte nonce.
|
||||
*/
|
||||
exports.salsa20 = (0, _arx_js_1.createCipher)(salsaCore, {
|
||||
allowShortKeys: true,
|
||||
counterRight: true,
|
||||
});
|
||||
/**
|
||||
* xsalsa20, 24-byte nonce.
|
||||
*/
|
||||
exports.xsalsa20 = (0, _arx_js_1.createCipher)(salsaCore, {
|
||||
counterRight: true,
|
||||
extendNonceFn: hsalsa,
|
||||
});
|
||||
/**
|
||||
* chacha20 non-RFC, original version by djb. 8-byte nonce, 8-byte counter.
|
||||
*/
|
||||
exports.chacha20orig = (0, _arx_js_1.createCipher)(chachaCore, {
|
||||
allowShortKeys: true,
|
||||
counterRight: false,
|
||||
counterLength: 8,
|
||||
});
|
||||
/**
|
||||
* chacha20 RFC 8439 (IETF / TLS). 12-byte nonce, 4-byte counter.
|
||||
*/
|
||||
exports.chacha20 = (0, _arx_js_1.createCipher)(chachaCore, {
|
||||
counterRight: false,
|
||||
counterLength: 4,
|
||||
});
|
||||
/**
|
||||
* xchacha20 eXtended-nonce. https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-xchacha
|
||||
*/
|
||||
exports.xchacha20 = (0, _arx_js_1.createCipher)(chachaCore, {
|
||||
counterRight: false,
|
||||
counterLength: 8,
|
||||
extendNonceFn: hchacha,
|
||||
});
|
||||
/**
|
||||
* 8-round chacha from the original paper.
|
||||
*/
|
||||
exports.chacha8 = (0, _arx_js_1.createCipher)(chachaCore, {
|
||||
counterRight: false,
|
||||
counterLength: 4,
|
||||
rounds: 8,
|
||||
});
|
||||
/**
|
||||
* 12-round chacha from the original paper.
|
||||
*/
|
||||
exports.chacha12 = (0, _arx_js_1.createCipher)(chachaCore, {
|
||||
counterRight: false,
|
||||
counterLength: 4,
|
||||
rounds: 12,
|
||||
});
|
||||
const POW_2_130_5 = BigInt(2) ** BigInt(130) - BigInt(5);
|
||||
const POW_2_128_1 = BigInt(2) ** BigInt(16 * 8) - BigInt(1);
|
||||
const CLAMP_R = BigInt('0x0ffffffc0ffffffc0ffffffc0fffffff');
|
||||
const _0 = BigInt(0);
|
||||
const _1 = BigInt(1);
|
||||
// Can be speed-up using BigUint64Array, but would be more complicated
|
||||
function poly1305(msg, key) {
|
||||
(0, _assert_js_1.bytes)(msg);
|
||||
(0, _assert_js_1.bytes)(key);
|
||||
let acc = _0;
|
||||
const r = bytesToNumberLE(key.subarray(0, 16)) & CLAMP_R;
|
||||
const s = bytesToNumberLE(key.subarray(16));
|
||||
// Process by 16 byte chunks
|
||||
for (let i = 0; i < msg.length; i += 16) {
|
||||
const m = msg.subarray(i, i + 16);
|
||||
const n = bytesToNumberLE(m) | (_1 << BigInt(8 * m.length));
|
||||
acc = ((acc + n) * r) % POW_2_130_5;
|
||||
}
|
||||
const res = (acc + s) & POW_2_128_1;
|
||||
return numberToBytesLE(res, 16);
|
||||
}
|
||||
exports.poly1305 = poly1305;
|
||||
function computeTag(fn, key, nonce, ciphertext, AAD) {
|
||||
const res = [];
|
||||
if (AAD) {
|
||||
res.push(AAD);
|
||||
const leftover = AAD.length % 16;
|
||||
if (leftover > 0)
|
||||
res.push(new Uint8Array(16 - leftover));
|
||||
}
|
||||
res.push(ciphertext);
|
||||
const leftover = ciphertext.length % 16;
|
||||
if (leftover > 0)
|
||||
res.push(new Uint8Array(16 - leftover));
|
||||
// Lengths
|
||||
const num = new Uint8Array(16);
|
||||
const view = (0, utils_js_1.createView)(num);
|
||||
(0, utils_js_1.setBigUint64)(view, 0, BigInt(AAD ? AAD.length : 0), true);
|
||||
(0, utils_js_1.setBigUint64)(view, 8, BigInt(ciphertext.length), true);
|
||||
res.push(num);
|
||||
const authKey = fn(key, nonce, new Uint8Array(32));
|
||||
return poly1305((0, utils_js_1.concatBytes)(...res), authKey);
|
||||
}
|
||||
/**
|
||||
* xsalsa20-poly1305 eXtended-nonce (24 bytes) salsa.
|
||||
*/
|
||||
exports.xsalsa20poly1305 = (0, utils_js_1.wrapCipher)({ blockSize: 64, nonceLength: 24, tagLength: 16 }, function xsalsa20poly1305(key, nonce) {
|
||||
(0, _assert_js_1.bytes)(key);
|
||||
(0, _assert_js_1.bytes)(nonce);
|
||||
return {
|
||||
encrypt: (plaintext) => {
|
||||
(0, _assert_js_1.bytes)(plaintext);
|
||||
const m = (0, utils_js_1.concatBytes)(new Uint8Array(32), plaintext);
|
||||
const c = (0, exports.xsalsa20)(key, nonce, m);
|
||||
const authKey = c.subarray(0, 32);
|
||||
const data = c.subarray(32);
|
||||
const tag = poly1305(data, authKey);
|
||||
return (0, utils_js_1.concatBytes)(tag, data);
|
||||
},
|
||||
decrypt: (ciphertext) => {
|
||||
(0, _assert_js_1.bytes)(ciphertext);
|
||||
if (ciphertext.length < 16)
|
||||
throw new Error('encrypted data must be at least 16 bytes');
|
||||
const c = (0, utils_js_1.concatBytes)(new Uint8Array(16), ciphertext);
|
||||
const authKey = (0, exports.xsalsa20)(key, nonce, new Uint8Array(32));
|
||||
const tag = poly1305(c.subarray(32), authKey);
|
||||
if (!(0, utils_js_1.equalBytes)(c.subarray(16, 32), tag))
|
||||
throw new Error('invalid poly1305 tag');
|
||||
return (0, exports.xsalsa20)(key, nonce, c).subarray(32);
|
||||
},
|
||||
};
|
||||
});
|
||||
/**
|
||||
* Alias to xsalsa20-poly1305
|
||||
*/
|
||||
function secretbox(key, nonce) {
|
||||
const xs = (0, exports.xsalsa20poly1305)(key, nonce);
|
||||
return { seal: xs.encrypt, open: xs.decrypt };
|
||||
}
|
||||
exports.secretbox = secretbox;
|
||||
const _poly1305_aead = (fn) => (key, nonce, AAD) => {
|
||||
const tagLength = 16;
|
||||
const keyLength = 32;
|
||||
(0, _assert_js_1.bytes)(key, keyLength);
|
||||
(0, _assert_js_1.bytes)(nonce);
|
||||
return {
|
||||
encrypt: (plaintext) => {
|
||||
(0, _assert_js_1.bytes)(plaintext);
|
||||
const res = fn(key, nonce, plaintext, undefined, 1);
|
||||
const tag = computeTag(fn, key, nonce, res, AAD);
|
||||
return (0, utils_js_1.concatBytes)(res, tag);
|
||||
},
|
||||
decrypt: (ciphertext) => {
|
||||
(0, _assert_js_1.bytes)(ciphertext);
|
||||
if (ciphertext.length < tagLength)
|
||||
throw new Error(`encrypted data must be at least ${tagLength} bytes`);
|
||||
const passedTag = ciphertext.subarray(-tagLength);
|
||||
const data = ciphertext.subarray(0, -tagLength);
|
||||
const tag = computeTag(fn, key, nonce, data, AAD);
|
||||
if (!(0, utils_js_1.equalBytes)(passedTag, tag))
|
||||
throw new Error('invalid poly1305 tag');
|
||||
return fn(key, nonce, data, undefined, 1);
|
||||
},
|
||||
};
|
||||
};
|
||||
exports._poly1305_aead = _poly1305_aead;
|
||||
/**
|
||||
* chacha20-poly1305 12-byte-nonce chacha.
|
||||
*/
|
||||
exports.chacha20poly1305 = (0, utils_js_1.wrapCipher)({ blockSize: 64, nonceLength: 12, tagLength: 16 }, (0, exports._poly1305_aead)(exports.chacha20));
|
||||
/**
|
||||
* xchacha20-poly1305 eXtended-nonce (24 bytes) chacha.
|
||||
* With 24-byte nonce, it's safe to use fill it with random (CSPRNG).
|
||||
*/
|
||||
exports.xchacha20poly1305 = (0, utils_js_1.wrapCipher)({ blockSize: 64, nonceLength: 24, tagLength: 16 }, (0, exports._poly1305_aead)(exports.xchacha20));
|
||||
//# sourceMappingURL=_micro.js.map
|
||||
1
thrower_daemon/node_modules/@noble/ciphers/_micro.js.map
generated
vendored
Normal file
1
thrower_daemon/node_modules/@noble/ciphers/_micro.js.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
15
thrower_daemon/node_modules/@noble/ciphers/_poly1305.d.ts
generated
vendored
Normal file
15
thrower_daemon/node_modules/@noble/ciphers/_poly1305.d.ts
generated
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
import { Input, Hash } from './utils.js';
|
||||
export type CHash = ReturnType<typeof wrapConstructorWithKey>;
|
||||
export declare function wrapConstructorWithKey<H extends Hash<H>>(hashCons: (key: Input) => Hash<H>): {
|
||||
(msg: Input, key: Input): Uint8Array;
|
||||
outputLen: number;
|
||||
blockLen: number;
|
||||
create(key: Input): Hash<H>;
|
||||
};
|
||||
export declare const poly1305: {
|
||||
(msg: Input, key: Input): Uint8Array;
|
||||
outputLen: number;
|
||||
blockLen: number;
|
||||
create(key: Input): Hash<Hash<unknown>>;
|
||||
};
|
||||
//# sourceMappingURL=_poly1305.d.ts.map
|
||||
1
thrower_daemon/node_modules/@noble/ciphers/_poly1305.d.ts.map
generated
vendored
Normal file
1
thrower_daemon/node_modules/@noble/ciphers/_poly1305.d.ts.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"_poly1305.d.ts","sourceRoot":"","sources":["src/_poly1305.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,EAAW,IAAI,EAAE,MAAM,YAAY,CAAC;AAkRlD,MAAM,MAAM,KAAK,GAAG,UAAU,CAAC,OAAO,sBAAsB,CAAC,CAAC;AAC9D,wBAAgB,sBAAsB,CAAC,CAAC,SAAS,IAAI,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,GAAG,EAAE,KAAK,KAAK,IAAI,CAAC,CAAC,CAAC;UACrE,KAAK,OAAO,KAAK,GAAG,UAAU;;;gBAI7B,KAAK;EAE3B;AAED,eAAO,MAAM,QAAQ;UARC,KAAK,OAAO,KAAK,GAAG,UAAU;;;gBAI7B,KAAK;CAI8C,CAAC"}
|
||||
268
thrower_daemon/node_modules/@noble/ciphers/_poly1305.js
generated
vendored
Normal file
268
thrower_daemon/node_modules/@noble/ciphers/_poly1305.js
generated
vendored
Normal file
@@ -0,0 +1,268 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.poly1305 = exports.wrapConstructorWithKey = void 0;
|
||||
const _assert_js_1 = require("./_assert.js");
|
||||
const utils_js_1 = require("./utils.js");
|
||||
// Poly1305 is a fast and parallel secret-key message-authentication code.
|
||||
// https://cr.yp.to/mac.html, https://cr.yp.to/mac/poly1305-20050329.pdf
|
||||
// https://datatracker.ietf.org/doc/html/rfc8439
|
||||
// Based on Public Domain poly1305-donna https://github.com/floodyberry/poly1305-donna
|
||||
const u8to16 = (a, i) => (a[i++] & 0xff) | ((a[i++] & 0xff) << 8);
|
||||
class Poly1305 {
|
||||
constructor(key) {
|
||||
this.blockLen = 16;
|
||||
this.outputLen = 16;
|
||||
this.buffer = new Uint8Array(16);
|
||||
this.r = new Uint16Array(10);
|
||||
this.h = new Uint16Array(10);
|
||||
this.pad = new Uint16Array(8);
|
||||
this.pos = 0;
|
||||
this.finished = false;
|
||||
key = (0, utils_js_1.toBytes)(key);
|
||||
(0, _assert_js_1.bytes)(key, 32);
|
||||
const t0 = u8to16(key, 0);
|
||||
const t1 = u8to16(key, 2);
|
||||
const t2 = u8to16(key, 4);
|
||||
const t3 = u8to16(key, 6);
|
||||
const t4 = u8to16(key, 8);
|
||||
const t5 = u8to16(key, 10);
|
||||
const t6 = u8to16(key, 12);
|
||||
const t7 = u8to16(key, 14);
|
||||
// https://github.com/floodyberry/poly1305-donna/blob/e6ad6e091d30d7f4ec2d4f978be1fcfcbce72781/poly1305-donna-16.h#L47
|
||||
this.r[0] = t0 & 0x1fff;
|
||||
this.r[1] = ((t0 >>> 13) | (t1 << 3)) & 0x1fff;
|
||||
this.r[2] = ((t1 >>> 10) | (t2 << 6)) & 0x1f03;
|
||||
this.r[3] = ((t2 >>> 7) | (t3 << 9)) & 0x1fff;
|
||||
this.r[4] = ((t3 >>> 4) | (t4 << 12)) & 0x00ff;
|
||||
this.r[5] = (t4 >>> 1) & 0x1ffe;
|
||||
this.r[6] = ((t4 >>> 14) | (t5 << 2)) & 0x1fff;
|
||||
this.r[7] = ((t5 >>> 11) | (t6 << 5)) & 0x1f81;
|
||||
this.r[8] = ((t6 >>> 8) | (t7 << 8)) & 0x1fff;
|
||||
this.r[9] = (t7 >>> 5) & 0x007f;
|
||||
for (let i = 0; i < 8; i++)
|
||||
this.pad[i] = u8to16(key, 16 + 2 * i);
|
||||
}
|
||||
process(data, offset, isLast = false) {
|
||||
const hibit = isLast ? 0 : 1 << 11;
|
||||
const { h, r } = this;
|
||||
const r0 = r[0];
|
||||
const r1 = r[1];
|
||||
const r2 = r[2];
|
||||
const r3 = r[3];
|
||||
const r4 = r[4];
|
||||
const r5 = r[5];
|
||||
const r6 = r[6];
|
||||
const r7 = r[7];
|
||||
const r8 = r[8];
|
||||
const r9 = r[9];
|
||||
const t0 = u8to16(data, offset + 0);
|
||||
const t1 = u8to16(data, offset + 2);
|
||||
const t2 = u8to16(data, offset + 4);
|
||||
const t3 = u8to16(data, offset + 6);
|
||||
const t4 = u8to16(data, offset + 8);
|
||||
const t5 = u8to16(data, offset + 10);
|
||||
const t6 = u8to16(data, offset + 12);
|
||||
const t7 = u8to16(data, offset + 14);
|
||||
let h0 = h[0] + (t0 & 0x1fff);
|
||||
let h1 = h[1] + (((t0 >>> 13) | (t1 << 3)) & 0x1fff);
|
||||
let h2 = h[2] + (((t1 >>> 10) | (t2 << 6)) & 0x1fff);
|
||||
let h3 = h[3] + (((t2 >>> 7) | (t3 << 9)) & 0x1fff);
|
||||
let h4 = h[4] + (((t3 >>> 4) | (t4 << 12)) & 0x1fff);
|
||||
let h5 = h[5] + ((t4 >>> 1) & 0x1fff);
|
||||
let h6 = h[6] + (((t4 >>> 14) | (t5 << 2)) & 0x1fff);
|
||||
let h7 = h[7] + (((t5 >>> 11) | (t6 << 5)) & 0x1fff);
|
||||
let h8 = h[8] + (((t6 >>> 8) | (t7 << 8)) & 0x1fff);
|
||||
let h9 = h[9] + ((t7 >>> 5) | hibit);
|
||||
let c = 0;
|
||||
let d0 = c + h0 * r0 + h1 * (5 * r9) + h2 * (5 * r8) + h3 * (5 * r7) + h4 * (5 * r6);
|
||||
c = d0 >>> 13;
|
||||
d0 &= 0x1fff;
|
||||
d0 += h5 * (5 * r5) + h6 * (5 * r4) + h7 * (5 * r3) + h8 * (5 * r2) + h9 * (5 * r1);
|
||||
c += d0 >>> 13;
|
||||
d0 &= 0x1fff;
|
||||
let d1 = c + h0 * r1 + h1 * r0 + h2 * (5 * r9) + h3 * (5 * r8) + h4 * (5 * r7);
|
||||
c = d1 >>> 13;
|
||||
d1 &= 0x1fff;
|
||||
d1 += h5 * (5 * r6) + h6 * (5 * r5) + h7 * (5 * r4) + h8 * (5 * r3) + h9 * (5 * r2);
|
||||
c += d1 >>> 13;
|
||||
d1 &= 0x1fff;
|
||||
let d2 = c + h0 * r2 + h1 * r1 + h2 * r0 + h3 * (5 * r9) + h4 * (5 * r8);
|
||||
c = d2 >>> 13;
|
||||
d2 &= 0x1fff;
|
||||
d2 += h5 * (5 * r7) + h6 * (5 * r6) + h7 * (5 * r5) + h8 * (5 * r4) + h9 * (5 * r3);
|
||||
c += d2 >>> 13;
|
||||
d2 &= 0x1fff;
|
||||
let d3 = c + h0 * r3 + h1 * r2 + h2 * r1 + h3 * r0 + h4 * (5 * r9);
|
||||
c = d3 >>> 13;
|
||||
d3 &= 0x1fff;
|
||||
d3 += h5 * (5 * r8) + h6 * (5 * r7) + h7 * (5 * r6) + h8 * (5 * r5) + h9 * (5 * r4);
|
||||
c += d3 >>> 13;
|
||||
d3 &= 0x1fff;
|
||||
let d4 = c + h0 * r4 + h1 * r3 + h2 * r2 + h3 * r1 + h4 * r0;
|
||||
c = d4 >>> 13;
|
||||
d4 &= 0x1fff;
|
||||
d4 += h5 * (5 * r9) + h6 * (5 * r8) + h7 * (5 * r7) + h8 * (5 * r6) + h9 * (5 * r5);
|
||||
c += d4 >>> 13;
|
||||
d4 &= 0x1fff;
|
||||
let d5 = c + h0 * r5 + h1 * r4 + h2 * r3 + h3 * r2 + h4 * r1;
|
||||
c = d5 >>> 13;
|
||||
d5 &= 0x1fff;
|
||||
d5 += h5 * r0 + h6 * (5 * r9) + h7 * (5 * r8) + h8 * (5 * r7) + h9 * (5 * r6);
|
||||
c += d5 >>> 13;
|
||||
d5 &= 0x1fff;
|
||||
let d6 = c + h0 * r6 + h1 * r5 + h2 * r4 + h3 * r3 + h4 * r2;
|
||||
c = d6 >>> 13;
|
||||
d6 &= 0x1fff;
|
||||
d6 += h5 * r1 + h6 * r0 + h7 * (5 * r9) + h8 * (5 * r8) + h9 * (5 * r7);
|
||||
c += d6 >>> 13;
|
||||
d6 &= 0x1fff;
|
||||
let d7 = c + h0 * r7 + h1 * r6 + h2 * r5 + h3 * r4 + h4 * r3;
|
||||
c = d7 >>> 13;
|
||||
d7 &= 0x1fff;
|
||||
d7 += h5 * r2 + h6 * r1 + h7 * r0 + h8 * (5 * r9) + h9 * (5 * r8);
|
||||
c += d7 >>> 13;
|
||||
d7 &= 0x1fff;
|
||||
let d8 = c + h0 * r8 + h1 * r7 + h2 * r6 + h3 * r5 + h4 * r4;
|
||||
c = d8 >>> 13;
|
||||
d8 &= 0x1fff;
|
||||
d8 += h5 * r3 + h6 * r2 + h7 * r1 + h8 * r0 + h9 * (5 * r9);
|
||||
c += d8 >>> 13;
|
||||
d8 &= 0x1fff;
|
||||
let d9 = c + h0 * r9 + h1 * r8 + h2 * r7 + h3 * r6 + h4 * r5;
|
||||
c = d9 >>> 13;
|
||||
d9 &= 0x1fff;
|
||||
d9 += h5 * r4 + h6 * r3 + h7 * r2 + h8 * r1 + h9 * r0;
|
||||
c += d9 >>> 13;
|
||||
d9 &= 0x1fff;
|
||||
c = ((c << 2) + c) | 0;
|
||||
c = (c + d0) | 0;
|
||||
d0 = c & 0x1fff;
|
||||
c = c >>> 13;
|
||||
d1 += c;
|
||||
h[0] = d0;
|
||||
h[1] = d1;
|
||||
h[2] = d2;
|
||||
h[3] = d3;
|
||||
h[4] = d4;
|
||||
h[5] = d5;
|
||||
h[6] = d6;
|
||||
h[7] = d7;
|
||||
h[8] = d8;
|
||||
h[9] = d9;
|
||||
}
|
||||
finalize() {
|
||||
const { h, pad } = this;
|
||||
const g = new Uint16Array(10);
|
||||
let c = h[1] >>> 13;
|
||||
h[1] &= 0x1fff;
|
||||
for (let i = 2; i < 10; i++) {
|
||||
h[i] += c;
|
||||
c = h[i] >>> 13;
|
||||
h[i] &= 0x1fff;
|
||||
}
|
||||
h[0] += c * 5;
|
||||
c = h[0] >>> 13;
|
||||
h[0] &= 0x1fff;
|
||||
h[1] += c;
|
||||
c = h[1] >>> 13;
|
||||
h[1] &= 0x1fff;
|
||||
h[2] += c;
|
||||
g[0] = h[0] + 5;
|
||||
c = g[0] >>> 13;
|
||||
g[0] &= 0x1fff;
|
||||
for (let i = 1; i < 10; i++) {
|
||||
g[i] = h[i] + c;
|
||||
c = g[i] >>> 13;
|
||||
g[i] &= 0x1fff;
|
||||
}
|
||||
g[9] -= 1 << 13;
|
||||
let mask = (c ^ 1) - 1;
|
||||
for (let i = 0; i < 10; i++)
|
||||
g[i] &= mask;
|
||||
mask = ~mask;
|
||||
for (let i = 0; i < 10; i++)
|
||||
h[i] = (h[i] & mask) | g[i];
|
||||
h[0] = (h[0] | (h[1] << 13)) & 0xffff;
|
||||
h[1] = ((h[1] >>> 3) | (h[2] << 10)) & 0xffff;
|
||||
h[2] = ((h[2] >>> 6) | (h[3] << 7)) & 0xffff;
|
||||
h[3] = ((h[3] >>> 9) | (h[4] << 4)) & 0xffff;
|
||||
h[4] = ((h[4] >>> 12) | (h[5] << 1) | (h[6] << 14)) & 0xffff;
|
||||
h[5] = ((h[6] >>> 2) | (h[7] << 11)) & 0xffff;
|
||||
h[6] = ((h[7] >>> 5) | (h[8] << 8)) & 0xffff;
|
||||
h[7] = ((h[8] >>> 8) | (h[9] << 5)) & 0xffff;
|
||||
let f = h[0] + pad[0];
|
||||
h[0] = f & 0xffff;
|
||||
for (let i = 1; i < 8; i++) {
|
||||
f = (((h[i] + pad[i]) | 0) + (f >>> 16)) | 0;
|
||||
h[i] = f & 0xffff;
|
||||
}
|
||||
}
|
||||
update(data) {
|
||||
(0, _assert_js_1.exists)(this);
|
||||
const { buffer, blockLen } = this;
|
||||
data = (0, utils_js_1.toBytes)(data);
|
||||
const len = data.length;
|
||||
for (let pos = 0; pos < len;) {
|
||||
const take = Math.min(blockLen - this.pos, len - pos);
|
||||
// Fast path: we have at least one block in input
|
||||
if (take === blockLen) {
|
||||
for (; blockLen <= len - pos; pos += blockLen)
|
||||
this.process(data, pos);
|
||||
continue;
|
||||
}
|
||||
buffer.set(data.subarray(pos, pos + take), this.pos);
|
||||
this.pos += take;
|
||||
pos += take;
|
||||
if (this.pos === blockLen) {
|
||||
this.process(buffer, 0, false);
|
||||
this.pos = 0;
|
||||
}
|
||||
}
|
||||
return this;
|
||||
}
|
||||
destroy() {
|
||||
this.h.fill(0);
|
||||
this.r.fill(0);
|
||||
this.buffer.fill(0);
|
||||
this.pad.fill(0);
|
||||
}
|
||||
digestInto(out) {
|
||||
(0, _assert_js_1.exists)(this);
|
||||
(0, _assert_js_1.output)(out, this);
|
||||
this.finished = true;
|
||||
const { buffer, h } = this;
|
||||
let { pos } = this;
|
||||
if (pos) {
|
||||
buffer[pos++] = 1;
|
||||
// buffer.subarray(pos).fill(0);
|
||||
for (; pos < 16; pos++)
|
||||
buffer[pos] = 0;
|
||||
this.process(buffer, 0, true);
|
||||
}
|
||||
this.finalize();
|
||||
let opos = 0;
|
||||
for (let i = 0; i < 8; i++) {
|
||||
out[opos++] = h[i] >>> 0;
|
||||
out[opos++] = h[i] >>> 8;
|
||||
}
|
||||
return out;
|
||||
}
|
||||
digest() {
|
||||
const { buffer, outputLen } = this;
|
||||
this.digestInto(buffer);
|
||||
const res = buffer.slice(0, outputLen);
|
||||
this.destroy();
|
||||
return res;
|
||||
}
|
||||
}
|
||||
function wrapConstructorWithKey(hashCons) {
|
||||
const hashC = (msg, key) => hashCons(key).update((0, utils_js_1.toBytes)(msg)).digest();
|
||||
const tmp = hashCons(new Uint8Array(32));
|
||||
hashC.outputLen = tmp.outputLen;
|
||||
hashC.blockLen = tmp.blockLen;
|
||||
hashC.create = (key) => hashCons(key);
|
||||
return hashC;
|
||||
}
|
||||
exports.wrapConstructorWithKey = wrapConstructorWithKey;
|
||||
exports.poly1305 = wrapConstructorWithKey((key) => new Poly1305(key));
|
||||
//# sourceMappingURL=_poly1305.js.map
|
||||
1
thrower_daemon/node_modules/@noble/ciphers/_poly1305.js.map
generated
vendored
Normal file
1
thrower_daemon/node_modules/@noble/ciphers/_poly1305.js.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
27
thrower_daemon/node_modules/@noble/ciphers/_polyval.d.ts
generated
vendored
Normal file
27
thrower_daemon/node_modules/@noble/ciphers/_polyval.d.ts
generated
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
import { Input, Hash } from './utils.js';
|
||||
/**
|
||||
* `mulX_POLYVAL(ByteReverse(H))` from spec
|
||||
* @param k mutated in place
|
||||
*/
|
||||
export declare function _toGHASHKey(k: Uint8Array): Uint8Array;
|
||||
export type CHash = ReturnType<typeof wrapConstructorWithKey>;
|
||||
declare function wrapConstructorWithKey<H extends Hash<H>>(hashCons: (key: Input, expectedLength?: number) => Hash<H>): {
|
||||
(msg: Input, key: Input): Uint8Array;
|
||||
outputLen: number;
|
||||
blockLen: number;
|
||||
create(key: Input, expectedLength?: number): Hash<H>;
|
||||
};
|
||||
export declare const ghash: {
|
||||
(msg: Input, key: Input): Uint8Array;
|
||||
outputLen: number;
|
||||
blockLen: number;
|
||||
create(key: Input, expectedLength?: number): Hash<Hash<unknown>>;
|
||||
};
|
||||
export declare const polyval: {
|
||||
(msg: Input, key: Input): Uint8Array;
|
||||
outputLen: number;
|
||||
blockLen: number;
|
||||
create(key: Input, expectedLength?: number): Hash<Hash<unknown>>;
|
||||
};
|
||||
export {};
|
||||
//# sourceMappingURL=_polyval.d.ts.map
|
||||
1
thrower_daemon/node_modules/@noble/ciphers/_polyval.d.ts.map
generated
vendored
Normal file
1
thrower_daemon/node_modules/@noble/ciphers/_polyval.d.ts.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"_polyval.d.ts","sourceRoot":"","sources":["src/_polyval.ts"],"names":[],"mappings":"AAAA,OAAO,EAAuB,KAAK,EAAE,IAAI,EAAO,MAAM,YAAY,CAAC;AAsCnE;;;GAGG;AACH,wBAAgB,WAAW,CAAC,CAAC,EAAE,UAAU,GAAG,UAAU,CAYrD;AA+KD,MAAM,MAAM,KAAK,GAAG,UAAU,CAAC,OAAO,sBAAsB,CAAC,CAAC;AAC9D,iBAAS,sBAAsB,CAAC,CAAC,SAAS,IAAI,CAAC,CAAC,CAAC,EAC/C,QAAQ,EAAE,CAAC,GAAG,EAAE,KAAK,EAAE,cAAc,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC,CAAC,CAAC;UAEtC,KAAK,OAAO,KAAK,GAAG,UAAU;;;gBAK7B,KAAK,mBAAmB,MAAM;EAEpD;AAED,eAAO,MAAM,KAAK;UATI,KAAK,OAAO,KAAK,GAAG,UAAU;;;gBAK7B,KAAK,mBAAmB,MAAM;CAMpD,CAAC;AACF,eAAO,MAAM,OAAO;UAZE,KAAK,OAAO,KAAK,GAAG,UAAU;;;gBAK7B,KAAK,mBAAmB,MAAM;CASpD,CAAC"}
|
||||
221
thrower_daemon/node_modules/@noble/ciphers/_polyval.js
generated
vendored
Normal file
221
thrower_daemon/node_modules/@noble/ciphers/_polyval.js
generated
vendored
Normal file
@@ -0,0 +1,221 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.polyval = exports.ghash = exports._toGHASHKey = void 0;
|
||||
const utils_js_1 = require("./utils.js");
|
||||
const _assert_js_1 = require("./_assert.js");
|
||||
// GHash from AES-GCM and its little-endian "mirror image" Polyval from AES-SIV.
|
||||
// Implemented in terms of GHash with conversion function for keys
|
||||
// GCM GHASH from NIST SP800-38d, SIV from RFC 8452.
|
||||
// https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-38d.pdf
|
||||
// GHASH modulo: x^128 + x^7 + x^2 + x + 1
|
||||
// POLYVAL modulo: x^128 + x^127 + x^126 + x^121 + 1
|
||||
const BLOCK_SIZE = 16;
|
||||
// TODO: rewrite
|
||||
// temporary padding buffer
|
||||
const ZEROS16 = /* @__PURE__ */ new Uint8Array(16);
|
||||
const ZEROS32 = (0, utils_js_1.u32)(ZEROS16);
|
||||
const POLY = 0xe1; // v = 2*v % POLY
|
||||
// v = 2*v % POLY
|
||||
// NOTE: because x + x = 0 (add/sub is same), mul2(x) != x+x
|
||||
// We can multiply any number using montgomery ladder and this function (works as double, add is simple xor)
|
||||
const mul2 = (s0, s1, s2, s3) => {
|
||||
const hiBit = s3 & 1;
|
||||
return {
|
||||
s3: (s2 << 31) | (s3 >>> 1),
|
||||
s2: (s1 << 31) | (s2 >>> 1),
|
||||
s1: (s0 << 31) | (s1 >>> 1),
|
||||
s0: (s0 >>> 1) ^ ((POLY << 24) & -(hiBit & 1)), // reduce % poly
|
||||
};
|
||||
};
|
||||
const swapLE = (n) => (((n >>> 0) & 0xff) << 24) |
|
||||
(((n >>> 8) & 0xff) << 16) |
|
||||
(((n >>> 16) & 0xff) << 8) |
|
||||
((n >>> 24) & 0xff) |
|
||||
0;
|
||||
/**
|
||||
* `mulX_POLYVAL(ByteReverse(H))` from spec
|
||||
* @param k mutated in place
|
||||
*/
|
||||
function _toGHASHKey(k) {
|
||||
k.reverse();
|
||||
const hiBit = k[15] & 1;
|
||||
// k >>= 1
|
||||
let carry = 0;
|
||||
for (let i = 0; i < k.length; i++) {
|
||||
const t = k[i];
|
||||
k[i] = (t >>> 1) | carry;
|
||||
carry = (t & 1) << 7;
|
||||
}
|
||||
k[0] ^= -hiBit & 0xe1; // if (hiBit) n ^= 0xe1000000000000000000000000000000;
|
||||
return k;
|
||||
}
|
||||
exports._toGHASHKey = _toGHASHKey;
|
||||
const estimateWindow = (bytes) => {
|
||||
if (bytes > 64 * 1024)
|
||||
return 8;
|
||||
if (bytes > 1024)
|
||||
return 4;
|
||||
return 2;
|
||||
};
|
||||
class GHASH {
|
||||
// We select bits per window adaptively based on expectedLength
|
||||
constructor(key, expectedLength) {
|
||||
this.blockLen = BLOCK_SIZE;
|
||||
this.outputLen = BLOCK_SIZE;
|
||||
this.s0 = 0;
|
||||
this.s1 = 0;
|
||||
this.s2 = 0;
|
||||
this.s3 = 0;
|
||||
this.finished = false;
|
||||
key = (0, utils_js_1.toBytes)(key);
|
||||
(0, _assert_js_1.bytes)(key, 16);
|
||||
const kView = (0, utils_js_1.createView)(key);
|
||||
let k0 = kView.getUint32(0, false);
|
||||
let k1 = kView.getUint32(4, false);
|
||||
let k2 = kView.getUint32(8, false);
|
||||
let k3 = kView.getUint32(12, false);
|
||||
// generate table of doubled keys (half of montgomery ladder)
|
||||
const doubles = [];
|
||||
for (let i = 0; i < 128; i++) {
|
||||
doubles.push({ s0: swapLE(k0), s1: swapLE(k1), s2: swapLE(k2), s3: swapLE(k3) });
|
||||
({ s0: k0, s1: k1, s2: k2, s3: k3 } = mul2(k0, k1, k2, k3));
|
||||
}
|
||||
const W = estimateWindow(expectedLength || 1024);
|
||||
if (![1, 2, 4, 8].includes(W))
|
||||
throw new Error(`ghash: wrong window size=${W}, should be 2, 4 or 8`);
|
||||
this.W = W;
|
||||
const bits = 128; // always 128 bits;
|
||||
const windows = bits / W;
|
||||
const windowSize = (this.windowSize = 2 ** W);
|
||||
const items = [];
|
||||
// Create precompute table for window of W bits
|
||||
for (let w = 0; w < windows; w++) {
|
||||
// truth table: 00, 01, 10, 11
|
||||
for (let byte = 0; byte < windowSize; byte++) {
|
||||
// prettier-ignore
|
||||
let s0 = 0, s1 = 0, s2 = 0, s3 = 0;
|
||||
for (let j = 0; j < W; j++) {
|
||||
const bit = (byte >>> (W - j - 1)) & 1;
|
||||
if (!bit)
|
||||
continue;
|
||||
const { s0: d0, s1: d1, s2: d2, s3: d3 } = doubles[W * w + j];
|
||||
(s0 ^= d0), (s1 ^= d1), (s2 ^= d2), (s3 ^= d3);
|
||||
}
|
||||
items.push({ s0, s1, s2, s3 });
|
||||
}
|
||||
}
|
||||
this.t = items;
|
||||
}
|
||||
_updateBlock(s0, s1, s2, s3) {
|
||||
(s0 ^= this.s0), (s1 ^= this.s1), (s2 ^= this.s2), (s3 ^= this.s3);
|
||||
const { W, t, windowSize } = this;
|
||||
// prettier-ignore
|
||||
let o0 = 0, o1 = 0, o2 = 0, o3 = 0;
|
||||
const mask = (1 << W) - 1; // 2**W will kill performance.
|
||||
let w = 0;
|
||||
for (const num of [s0, s1, s2, s3]) {
|
||||
for (let bytePos = 0; bytePos < 4; bytePos++) {
|
||||
const byte = (num >>> (8 * bytePos)) & 0xff;
|
||||
for (let bitPos = 8 / W - 1; bitPos >= 0; bitPos--) {
|
||||
const bit = (byte >>> (W * bitPos)) & mask;
|
||||
const { s0: e0, s1: e1, s2: e2, s3: e3 } = t[w * windowSize + bit];
|
||||
(o0 ^= e0), (o1 ^= e1), (o2 ^= e2), (o3 ^= e3);
|
||||
w += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
this.s0 = o0;
|
||||
this.s1 = o1;
|
||||
this.s2 = o2;
|
||||
this.s3 = o3;
|
||||
}
|
||||
update(data) {
|
||||
data = (0, utils_js_1.toBytes)(data);
|
||||
(0, _assert_js_1.exists)(this);
|
||||
const b32 = (0, utils_js_1.u32)(data);
|
||||
const blocks = Math.floor(data.length / BLOCK_SIZE);
|
||||
const left = data.length % BLOCK_SIZE;
|
||||
for (let i = 0; i < blocks; i++) {
|
||||
this._updateBlock(b32[i * 4 + 0], b32[i * 4 + 1], b32[i * 4 + 2], b32[i * 4 + 3]);
|
||||
}
|
||||
if (left) {
|
||||
ZEROS16.set(data.subarray(blocks * BLOCK_SIZE));
|
||||
this._updateBlock(ZEROS32[0], ZEROS32[1], ZEROS32[2], ZEROS32[3]);
|
||||
ZEROS32.fill(0); // clean tmp buffer
|
||||
}
|
||||
return this;
|
||||
}
|
||||
destroy() {
|
||||
const { t } = this;
|
||||
// clean precompute table
|
||||
for (const elm of t) {
|
||||
(elm.s0 = 0), (elm.s1 = 0), (elm.s2 = 0), (elm.s3 = 0);
|
||||
}
|
||||
}
|
||||
digestInto(out) {
|
||||
(0, _assert_js_1.exists)(this);
|
||||
(0, _assert_js_1.output)(out, this);
|
||||
this.finished = true;
|
||||
const { s0, s1, s2, s3 } = this;
|
||||
const o32 = (0, utils_js_1.u32)(out);
|
||||
o32[0] = s0;
|
||||
o32[1] = s1;
|
||||
o32[2] = s2;
|
||||
o32[3] = s3;
|
||||
return out;
|
||||
}
|
||||
digest() {
|
||||
const res = new Uint8Array(BLOCK_SIZE);
|
||||
this.digestInto(res);
|
||||
this.destroy();
|
||||
return res;
|
||||
}
|
||||
}
|
||||
class Polyval extends GHASH {
|
||||
constructor(key, expectedLength) {
|
||||
key = (0, utils_js_1.toBytes)(key);
|
||||
const ghKey = _toGHASHKey(key.slice());
|
||||
super(ghKey, expectedLength);
|
||||
ghKey.fill(0);
|
||||
}
|
||||
update(data) {
|
||||
data = (0, utils_js_1.toBytes)(data);
|
||||
(0, _assert_js_1.exists)(this);
|
||||
const b32 = (0, utils_js_1.u32)(data);
|
||||
const left = data.length % BLOCK_SIZE;
|
||||
const blocks = Math.floor(data.length / BLOCK_SIZE);
|
||||
for (let i = 0; i < blocks; i++) {
|
||||
this._updateBlock(swapLE(b32[i * 4 + 3]), swapLE(b32[i * 4 + 2]), swapLE(b32[i * 4 + 1]), swapLE(b32[i * 4 + 0]));
|
||||
}
|
||||
if (left) {
|
||||
ZEROS16.set(data.subarray(blocks * BLOCK_SIZE));
|
||||
this._updateBlock(swapLE(ZEROS32[3]), swapLE(ZEROS32[2]), swapLE(ZEROS32[1]), swapLE(ZEROS32[0]));
|
||||
ZEROS32.fill(0); // clean tmp buffer
|
||||
}
|
||||
return this;
|
||||
}
|
||||
digestInto(out) {
|
||||
(0, _assert_js_1.exists)(this);
|
||||
(0, _assert_js_1.output)(out, this);
|
||||
this.finished = true;
|
||||
// tmp ugly hack
|
||||
const { s0, s1, s2, s3 } = this;
|
||||
const o32 = (0, utils_js_1.u32)(out);
|
||||
o32[0] = s0;
|
||||
o32[1] = s1;
|
||||
o32[2] = s2;
|
||||
o32[3] = s3;
|
||||
return out.reverse();
|
||||
}
|
||||
}
|
||||
function wrapConstructorWithKey(hashCons) {
|
||||
const hashC = (msg, key) => hashCons(key, msg.length).update((0, utils_js_1.toBytes)(msg)).digest();
|
||||
const tmp = hashCons(new Uint8Array(16), 0);
|
||||
hashC.outputLen = tmp.outputLen;
|
||||
hashC.blockLen = tmp.blockLen;
|
||||
hashC.create = (key, expectedLength) => hashCons(key, expectedLength);
|
||||
return hashC;
|
||||
}
|
||||
exports.ghash = wrapConstructorWithKey((key, expectedLength) => new GHASH(key, expectedLength));
|
||||
exports.polyval = wrapConstructorWithKey((key, expectedLength) => new Polyval(key, expectedLength));
|
||||
//# sourceMappingURL=_polyval.js.map
|
||||
1
thrower_daemon/node_modules/@noble/ciphers/_polyval.js.map
generated
vendored
Normal file
1
thrower_daemon/node_modules/@noble/ciphers/_polyval.js.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
86
thrower_daemon/node_modules/@noble/ciphers/aes.d.ts
generated
vendored
Normal file
86
thrower_daemon/node_modules/@noble/ciphers/aes.d.ts
generated
vendored
Normal file
@@ -0,0 +1,86 @@
|
||||
import { Cipher, CipherWithOutput } from './utils.js';
|
||||
export declare function expandKeyLE(key: Uint8Array): Uint32Array;
|
||||
export declare function expandKeyDecLE(key: Uint8Array): Uint32Array;
|
||||
declare function encrypt(xk: Uint32Array, s0: number, s1: number, s2: number, s3: number): {
|
||||
s0: number;
|
||||
s1: number;
|
||||
s2: number;
|
||||
s3: number;
|
||||
};
|
||||
declare function decrypt(xk: Uint32Array, s0: number, s1: number, s2: number, s3: number): {
|
||||
s0: number;
|
||||
s1: number;
|
||||
s2: number;
|
||||
s3: number;
|
||||
};
|
||||
declare function ctrCounter(xk: Uint32Array, nonce: Uint8Array, src: Uint8Array, dst?: Uint8Array): Uint8Array;
|
||||
declare function ctr32(xk: Uint32Array, isLE: boolean, nonce: Uint8Array, src: Uint8Array, dst?: Uint8Array): Uint8Array;
|
||||
/**
|
||||
* CTR: counter mode. Creates stream cipher.
|
||||
* Requires good IV. Parallelizable. OK, but no MAC.
|
||||
*/
|
||||
export declare const ctr: ((key: Uint8Array, nonce: Uint8Array) => CipherWithOutput) & {
|
||||
blockSize: number;
|
||||
nonceLength: number;
|
||||
};
|
||||
export type BlockOpts = {
|
||||
disablePadding?: boolean;
|
||||
};
|
||||
/**
|
||||
* ECB: Electronic CodeBook. Simple deterministic replacement.
|
||||
* Dangerous: always map x to y. See [AES Penguin](https://words.filippo.io/the-ecb-penguin/).
|
||||
*/
|
||||
export declare const ecb: ((key: Uint8Array, opts?: BlockOpts) => CipherWithOutput) & {
|
||||
blockSize: number;
|
||||
};
|
||||
/**
|
||||
* CBC: Cipher-Block-Chaining. Key is previous round’s block.
|
||||
* Fragile: needs proper padding. Unauthenticated: needs MAC.
|
||||
*/
|
||||
export declare const cbc: ((key: Uint8Array, iv: Uint8Array, opts?: BlockOpts) => CipherWithOutput) & {
|
||||
blockSize: number;
|
||||
nonceLength: number;
|
||||
};
|
||||
/**
|
||||
* CFB: Cipher Feedback Mode. The input for the block cipher is the previous cipher output.
|
||||
* Unauthenticated: needs MAC.
|
||||
*/
|
||||
export declare const cfb: ((key: Uint8Array, iv: Uint8Array) => CipherWithOutput) & {
|
||||
blockSize: number;
|
||||
nonceLength: number;
|
||||
};
|
||||
/**
|
||||
* GCM: Galois/Counter Mode.
|
||||
* Good, modern version of CTR, parallel, with MAC.
|
||||
* Be careful: MACs can be forged.
|
||||
*/
|
||||
export declare const gcm: ((key: Uint8Array, nonce: Uint8Array, AAD?: Uint8Array) => Cipher) & {
|
||||
blockSize: number;
|
||||
nonceLength: number;
|
||||
tagLength: number;
|
||||
};
|
||||
/**
|
||||
* AES-GCM-SIV: classic AES-GCM with nonce-misuse resistance.
|
||||
* Guarantees that, when a nonce is repeated, the only security loss is that identical
|
||||
* plaintexts will produce identical ciphertexts.
|
||||
* RFC 8452, https://datatracker.ietf.org/doc/html/rfc8452
|
||||
*/
|
||||
export declare const siv: ((key: Uint8Array, nonce: Uint8Array, AAD?: Uint8Array) => Cipher) & {
|
||||
blockSize: number;
|
||||
nonceLength: number;
|
||||
tagLength: number;
|
||||
};
|
||||
declare function encryptBlock(xk: Uint32Array, block: Uint8Array): Uint8Array;
|
||||
declare function decryptBlock(xk: Uint32Array, block: Uint8Array): Uint8Array;
|
||||
export declare const unsafe: {
|
||||
expandKeyLE: typeof expandKeyLE;
|
||||
expandKeyDecLE: typeof expandKeyDecLE;
|
||||
encrypt: typeof encrypt;
|
||||
decrypt: typeof decrypt;
|
||||
encryptBlock: typeof encryptBlock;
|
||||
decryptBlock: typeof decryptBlock;
|
||||
ctrCounter: typeof ctrCounter;
|
||||
ctr32: typeof ctr32;
|
||||
};
|
||||
export {};
|
||||
//# sourceMappingURL=aes.d.ts.map
|
||||
1
thrower_daemon/node_modules/@noble/ciphers/aes.d.ts.map
generated
vendored
Normal file
1
thrower_daemon/node_modules/@noble/ciphers/aes.d.ts.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"aes.d.ts","sourceRoot":"","sources":["src/aes.ts"],"names":[],"mappings":"AACA,OAAO,EACO,MAAM,EAAE,gBAAgB,EAErC,MAAM,YAAY,CAAC;AAmGpB,wBAAgB,WAAW,CAAC,GAAG,EAAE,UAAU,GAAG,WAAW,CAmBxD;AAED,wBAAgB,cAAc,CAAC,GAAG,EAAE,UAAU,GAAG,WAAW,CAkB3D;AAwBD,iBAAS,OAAO,CAAC,EAAE,EAAE,WAAW,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM;;;;;EAkB/E;AAED,iBAAS,OAAO,CAAC,EAAE,EAAE,WAAW,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM;;;;;EAkB/E;AAWD,iBAAS,UAAU,CAAC,EAAE,EAAE,WAAW,EAAE,KAAK,EAAE,UAAU,EAAE,GAAG,EAAE,UAAU,EAAE,GAAG,CAAC,EAAE,UAAU,cAmCxF;AAKD,iBAAS,KAAK,CACZ,EAAE,EAAE,WAAW,EACf,IAAI,EAAE,OAAO,EACb,KAAK,EAAE,UAAU,EACjB,GAAG,EAAE,UAAU,EACf,GAAG,CAAC,EAAE,UAAU,cAiCjB;AAED;;;GAGG;AACH,eAAO,MAAM,GAAG,SAEI,UAAU,SAAS,UAAU,KAAG,gBAAgB;;;CAgBnE,CAAC;AAgDF,MAAM,MAAM,SAAS,GAAG;IAAE,cAAc,CAAC,EAAE,OAAO,CAAA;CAAE,CAAC;AAErD;;;GAGG;AACH,eAAO,MAAM,GAAG,SAEI,UAAU,SAAQ,SAAS,KAAQ,gBAAgB;;CAoCtE,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,GAAG,SAEI,UAAU,MAAM,UAAU,SAAQ,SAAS,KAAQ,gBAAgB;;;CA+CtF,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,GAAG,SAEI,UAAU,MAAM,UAAU,KAAG,gBAAgB;;;CAqChE,CAAC;AAqBF;;;;GAIG;AACH,eAAO,MAAM,GAAG,SAEI,UAAU,SAAS,UAAU,QAAQ,UAAU,KAAG,MAAM;;;;CAyD3E,CAAC;AAOF;;;;;GAKG;AACH,eAAO,MAAM,GAAG,SAEI,UAAU,SAAS,UAAU,QAAQ,UAAU,KAAG,MAAM;;;;CAqF3E,CAAC;AAUF,iBAAS,YAAY,CAAC,EAAE,EAAE,WAAW,EAAE,KAAK,EAAE,UAAU,cAOvD;AAED,iBAAS,YAAY,CAAC,EAAE,EAAE,WAAW,EAAE,KAAK,EAAE,UAAU,cAOvD;AAID,eAAO,MAAM,MAAM;;;;;;;;;CASlB,CAAC"}
|
||||
675
thrower_daemon/node_modules/@noble/ciphers/aes.js
generated
vendored
Normal file
675
thrower_daemon/node_modules/@noble/ciphers/aes.js
generated
vendored
Normal file
@@ -0,0 +1,675 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.unsafe = exports.siv = exports.gcm = exports.cfb = exports.cbc = exports.ecb = exports.ctr = exports.expandKeyDecLE = exports.expandKeyLE = void 0;
|
||||
// prettier-ignore
|
||||
const utils_js_1 = require("./utils.js");
|
||||
const _polyval_js_1 = require("./_polyval.js");
|
||||
const _assert_js_1 = require("./_assert.js");
|
||||
/*
|
||||
AES (Advanced Encryption Standard) aka Rijndael block cipher.
|
||||
|
||||
Data is split into 128-bit blocks. Encrypted in 10/12/14 rounds (128/192/256 bits). In every round:
|
||||
1. **S-box**, table substitution
|
||||
2. **Shift rows**, cyclic shift left of all rows of data array
|
||||
3. **Mix columns**, multiplying every column by fixed polynomial
|
||||
4. **Add round key**, round_key xor i-th column of array
|
||||
|
||||
Resources:
|
||||
- FIPS-197 https://csrc.nist.gov/files/pubs/fips/197/final/docs/fips-197.pdf
|
||||
- Original proposal: https://csrc.nist.gov/csrc/media/projects/cryptographic-standards-and-guidelines/documents/aes-development/rijndael-ammended.pdf
|
||||
*/
|
||||
const BLOCK_SIZE = 16;
|
||||
const BLOCK_SIZE32 = 4;
|
||||
const EMPTY_BLOCK = new Uint8Array(BLOCK_SIZE);
|
||||
const POLY = 0x11b; // 1 + x + x**3 + x**4 + x**8
|
||||
// TODO: remove multiplication, binary ops only
|
||||
function mul2(n) {
|
||||
return (n << 1) ^ (POLY & -(n >> 7));
|
||||
}
|
||||
function mul(a, b) {
|
||||
let res = 0;
|
||||
for (; b > 0; b >>= 1) {
|
||||
// Montgomery ladder
|
||||
res ^= a & -(b & 1); // if (b&1) res ^=a (but const-time).
|
||||
a = mul2(a); // a = 2*a
|
||||
}
|
||||
return res;
|
||||
}
|
||||
// AES S-box is generated using finite field inversion,
|
||||
// an affine transform, and xor of a constant 0x63.
|
||||
const sbox = /* @__PURE__ */ (() => {
|
||||
let t = new Uint8Array(256);
|
||||
for (let i = 0, x = 1; i < 256; i++, x ^= mul2(x))
|
||||
t[i] = x;
|
||||
const box = new Uint8Array(256);
|
||||
box[0] = 0x63; // first elm
|
||||
for (let i = 0; i < 255; i++) {
|
||||
let x = t[255 - i];
|
||||
x |= x << 8;
|
||||
box[t[i]] = (x ^ (x >> 4) ^ (x >> 5) ^ (x >> 6) ^ (x >> 7) ^ 0x63) & 0xff;
|
||||
}
|
||||
return box;
|
||||
})();
|
||||
// Inverted S-box
|
||||
const invSbox = /* @__PURE__ */ sbox.map((_, j) => sbox.indexOf(j));
|
||||
// Rotate u32 by 8
|
||||
const rotr32_8 = (n) => (n << 24) | (n >>> 8);
|
||||
const rotl32_8 = (n) => (n << 8) | (n >>> 24);
|
||||
// T-table is optimization suggested in 5.2 of original proposal (missed from FIPS-197). Changes:
|
||||
// - LE instead of BE
|
||||
// - bigger tables: T0 and T1 are merged into T01 table and T2 & T3 into T23;
|
||||
// so index is u16, instead of u8. This speeds up things, unexpectedly
|
||||
function genTtable(sbox, fn) {
|
||||
if (sbox.length !== 256)
|
||||
throw new Error('Wrong sbox length');
|
||||
const T0 = new Uint32Array(256).map((_, j) => fn(sbox[j]));
|
||||
const T1 = T0.map(rotl32_8);
|
||||
const T2 = T1.map(rotl32_8);
|
||||
const T3 = T2.map(rotl32_8);
|
||||
const T01 = new Uint32Array(256 * 256);
|
||||
const T23 = new Uint32Array(256 * 256);
|
||||
const sbox2 = new Uint16Array(256 * 256);
|
||||
for (let i = 0; i < 256; i++) {
|
||||
for (let j = 0; j < 256; j++) {
|
||||
const idx = i * 256 + j;
|
||||
T01[idx] = T0[i] ^ T1[j];
|
||||
T23[idx] = T2[i] ^ T3[j];
|
||||
sbox2[idx] = (sbox[i] << 8) | sbox[j];
|
||||
}
|
||||
}
|
||||
return { sbox, sbox2, T0, T1, T2, T3, T01, T23 };
|
||||
}
|
||||
const tableEncoding = /* @__PURE__ */ genTtable(sbox, (s) => (mul(s, 3) << 24) | (s << 16) | (s << 8) | mul(s, 2));
|
||||
const tableDecoding = /* @__PURE__ */ genTtable(invSbox, (s) => (mul(s, 11) << 24) | (mul(s, 13) << 16) | (mul(s, 9) << 8) | mul(s, 14));
|
||||
const xPowers = /* @__PURE__ */ (() => {
|
||||
const p = new Uint8Array(16);
|
||||
for (let i = 0, x = 1; i < 16; i++, x = mul2(x))
|
||||
p[i] = x;
|
||||
return p;
|
||||
})();
|
||||
function expandKeyLE(key) {
|
||||
(0, _assert_js_1.bytes)(key);
|
||||
const len = key.length;
|
||||
if (![16, 24, 32].includes(len))
|
||||
throw new Error(`aes: wrong key size: should be 16, 24 or 32, got: ${len}`);
|
||||
const { sbox2 } = tableEncoding;
|
||||
const k32 = (0, utils_js_1.u32)(key);
|
||||
const Nk = k32.length;
|
||||
const subByte = (n) => applySbox(sbox2, n, n, n, n);
|
||||
const xk = new Uint32Array(len + 28); // expanded key
|
||||
xk.set(k32);
|
||||
// 4.3.1 Key expansion
|
||||
for (let i = Nk; i < xk.length; i++) {
|
||||
let t = xk[i - 1];
|
||||
if (i % Nk === 0)
|
||||
t = subByte(rotr32_8(t)) ^ xPowers[i / Nk - 1];
|
||||
else if (Nk > 6 && i % Nk === 4)
|
||||
t = subByte(t);
|
||||
xk[i] = xk[i - Nk] ^ t;
|
||||
}
|
||||
return xk;
|
||||
}
|
||||
exports.expandKeyLE = expandKeyLE;
|
||||
function expandKeyDecLE(key) {
|
||||
const encKey = expandKeyLE(key);
|
||||
const xk = encKey.slice();
|
||||
const Nk = encKey.length;
|
||||
const { sbox2 } = tableEncoding;
|
||||
const { T0, T1, T2, T3 } = tableDecoding;
|
||||
// Inverse key by chunks of 4 (rounds)
|
||||
for (let i = 0; i < Nk; i += 4) {
|
||||
for (let j = 0; j < 4; j++)
|
||||
xk[i + j] = encKey[Nk - i - 4 + j];
|
||||
}
|
||||
encKey.fill(0);
|
||||
// apply InvMixColumn except first & last round
|
||||
for (let i = 4; i < Nk - 4; i++) {
|
||||
const x = xk[i];
|
||||
const w = applySbox(sbox2, x, x, x, x);
|
||||
xk[i] = T0[w & 0xff] ^ T1[(w >>> 8) & 0xff] ^ T2[(w >>> 16) & 0xff] ^ T3[w >>> 24];
|
||||
}
|
||||
return xk;
|
||||
}
|
||||
exports.expandKeyDecLE = expandKeyDecLE;
|
||||
// Apply tables
|
||||
function apply0123(T01, T23, s0, s1, s2, s3) {
|
||||
return (T01[((s0 << 8) & 0xff00) | ((s1 >>> 8) & 0xff)] ^
|
||||
T23[((s2 >>> 8) & 0xff00) | ((s3 >>> 24) & 0xff)]);
|
||||
}
|
||||
function applySbox(sbox2, s0, s1, s2, s3) {
|
||||
return (sbox2[(s0 & 0xff) | (s1 & 0xff00)] |
|
||||
(sbox2[((s2 >>> 16) & 0xff) | ((s3 >>> 16) & 0xff00)] << 16));
|
||||
}
|
||||
function encrypt(xk, s0, s1, s2, s3) {
|
||||
const { sbox2, T01, T23 } = tableEncoding;
|
||||
let k = 0;
|
||||
(s0 ^= xk[k++]), (s1 ^= xk[k++]), (s2 ^= xk[k++]), (s3 ^= xk[k++]);
|
||||
const rounds = xk.length / 4 - 2;
|
||||
for (let i = 0; i < rounds; i++) {
|
||||
const t0 = xk[k++] ^ apply0123(T01, T23, s0, s1, s2, s3);
|
||||
const t1 = xk[k++] ^ apply0123(T01, T23, s1, s2, s3, s0);
|
||||
const t2 = xk[k++] ^ apply0123(T01, T23, s2, s3, s0, s1);
|
||||
const t3 = xk[k++] ^ apply0123(T01, T23, s3, s0, s1, s2);
|
||||
(s0 = t0), (s1 = t1), (s2 = t2), (s3 = t3);
|
||||
}
|
||||
// last round (without mixcolumns, so using SBOX2 table)
|
||||
const t0 = xk[k++] ^ applySbox(sbox2, s0, s1, s2, s3);
|
||||
const t1 = xk[k++] ^ applySbox(sbox2, s1, s2, s3, s0);
|
||||
const t2 = xk[k++] ^ applySbox(sbox2, s2, s3, s0, s1);
|
||||
const t3 = xk[k++] ^ applySbox(sbox2, s3, s0, s1, s2);
|
||||
return { s0: t0, s1: t1, s2: t2, s3: t3 };
|
||||
}
|
||||
function decrypt(xk, s0, s1, s2, s3) {
|
||||
const { sbox2, T01, T23 } = tableDecoding;
|
||||
let k = 0;
|
||||
(s0 ^= xk[k++]), (s1 ^= xk[k++]), (s2 ^= xk[k++]), (s3 ^= xk[k++]);
|
||||
const rounds = xk.length / 4 - 2;
|
||||
for (let i = 0; i < rounds; i++) {
|
||||
const t0 = xk[k++] ^ apply0123(T01, T23, s0, s3, s2, s1);
|
||||
const t1 = xk[k++] ^ apply0123(T01, T23, s1, s0, s3, s2);
|
||||
const t2 = xk[k++] ^ apply0123(T01, T23, s2, s1, s0, s3);
|
||||
const t3 = xk[k++] ^ apply0123(T01, T23, s3, s2, s1, s0);
|
||||
(s0 = t0), (s1 = t1), (s2 = t2), (s3 = t3);
|
||||
}
|
||||
// Last round
|
||||
const t0 = xk[k++] ^ applySbox(sbox2, s0, s3, s2, s1);
|
||||
const t1 = xk[k++] ^ applySbox(sbox2, s1, s0, s3, s2);
|
||||
const t2 = xk[k++] ^ applySbox(sbox2, s2, s1, s0, s3);
|
||||
const t3 = xk[k++] ^ applySbox(sbox2, s3, s2, s1, s0);
|
||||
return { s0: t0, s1: t1, s2: t2, s3: t3 };
|
||||
}
|
||||
function getDst(len, dst) {
|
||||
if (!dst)
|
||||
return new Uint8Array(len);
|
||||
(0, _assert_js_1.bytes)(dst);
|
||||
if (dst.length < len)
|
||||
throw new Error(`aes: wrong destination length, expected at least ${len}, got: ${dst.length}`);
|
||||
return dst;
|
||||
}
|
||||
// TODO: investigate merging with ctr32
|
||||
function ctrCounter(xk, nonce, src, dst) {
|
||||
(0, _assert_js_1.bytes)(nonce, BLOCK_SIZE);
|
||||
(0, _assert_js_1.bytes)(src);
|
||||
const srcLen = src.length;
|
||||
dst = getDst(srcLen, dst);
|
||||
const ctr = nonce;
|
||||
const c32 = (0, utils_js_1.u32)(ctr);
|
||||
// Fill block (empty, ctr=0)
|
||||
let { s0, s1, s2, s3 } = encrypt(xk, c32[0], c32[1], c32[2], c32[3]);
|
||||
const src32 = (0, utils_js_1.u32)(src);
|
||||
const dst32 = (0, utils_js_1.u32)(dst);
|
||||
// process blocks
|
||||
for (let i = 0; i + 4 <= src32.length; i += 4) {
|
||||
dst32[i + 0] = src32[i + 0] ^ s0;
|
||||
dst32[i + 1] = src32[i + 1] ^ s1;
|
||||
dst32[i + 2] = src32[i + 2] ^ s2;
|
||||
dst32[i + 3] = src32[i + 3] ^ s3;
|
||||
// Full 128 bit counter with wrap around
|
||||
let carry = 1;
|
||||
for (let i = ctr.length - 1; i >= 0; i--) {
|
||||
carry = (carry + (ctr[i] & 0xff)) | 0;
|
||||
ctr[i] = carry & 0xff;
|
||||
carry >>>= 8;
|
||||
}
|
||||
({ s0, s1, s2, s3 } = encrypt(xk, c32[0], c32[1], c32[2], c32[3]));
|
||||
}
|
||||
// leftovers (less than block)
|
||||
// It's possible to handle > u32 fast, but is it worth it?
|
||||
const start = BLOCK_SIZE * Math.floor(src32.length / BLOCK_SIZE32);
|
||||
if (start < srcLen) {
|
||||
const b32 = new Uint32Array([s0, s1, s2, s3]);
|
||||
const buf = (0, utils_js_1.u8)(b32);
|
||||
for (let i = start, pos = 0; i < srcLen; i++, pos++)
|
||||
dst[i] = src[i] ^ buf[pos];
|
||||
}
|
||||
return dst;
|
||||
}
|
||||
// AES CTR with overflowing 32 bit counter
|
||||
// It's possible to do 32le significantly simpler (and probably faster) by using u32.
|
||||
// But, we need both, and perf bottleneck is in ghash anyway.
|
||||
function ctr32(xk, isLE, nonce, src, dst) {
|
||||
(0, _assert_js_1.bytes)(nonce, BLOCK_SIZE);
|
||||
(0, _assert_js_1.bytes)(src);
|
||||
dst = getDst(src.length, dst);
|
||||
const ctr = nonce; // write new value to nonce, so it can be re-used
|
||||
const c32 = (0, utils_js_1.u32)(ctr);
|
||||
const view = (0, utils_js_1.createView)(ctr);
|
||||
const src32 = (0, utils_js_1.u32)(src);
|
||||
const dst32 = (0, utils_js_1.u32)(dst);
|
||||
const ctrPos = isLE ? 0 : 12;
|
||||
const srcLen = src.length;
|
||||
// Fill block (empty, ctr=0)
|
||||
let ctrNum = view.getUint32(ctrPos, isLE); // read current counter value
|
||||
let { s0, s1, s2, s3 } = encrypt(xk, c32[0], c32[1], c32[2], c32[3]);
|
||||
// process blocks
|
||||
for (let i = 0; i + 4 <= src32.length; i += 4) {
|
||||
dst32[i + 0] = src32[i + 0] ^ s0;
|
||||
dst32[i + 1] = src32[i + 1] ^ s1;
|
||||
dst32[i + 2] = src32[i + 2] ^ s2;
|
||||
dst32[i + 3] = src32[i + 3] ^ s3;
|
||||
ctrNum = (ctrNum + 1) >>> 0; // u32 wrap
|
||||
view.setUint32(ctrPos, ctrNum, isLE);
|
||||
({ s0, s1, s2, s3 } = encrypt(xk, c32[0], c32[1], c32[2], c32[3]));
|
||||
}
|
||||
// leftovers (less than a block)
|
||||
const start = BLOCK_SIZE * Math.floor(src32.length / BLOCK_SIZE32);
|
||||
if (start < srcLen) {
|
||||
const b32 = new Uint32Array([s0, s1, s2, s3]);
|
||||
const buf = (0, utils_js_1.u8)(b32);
|
||||
for (let i = start, pos = 0; i < srcLen; i++, pos++)
|
||||
dst[i] = src[i] ^ buf[pos];
|
||||
}
|
||||
return dst;
|
||||
}
|
||||
/**
|
||||
* CTR: counter mode. Creates stream cipher.
|
||||
* Requires good IV. Parallelizable. OK, but no MAC.
|
||||
*/
|
||||
exports.ctr = (0, utils_js_1.wrapCipher)({ blockSize: 16, nonceLength: 16 }, function ctr(key, nonce) {
|
||||
(0, _assert_js_1.bytes)(key);
|
||||
(0, _assert_js_1.bytes)(nonce, BLOCK_SIZE);
|
||||
function processCtr(buf, dst) {
|
||||
const xk = expandKeyLE(key);
|
||||
const n = nonce.slice();
|
||||
const out = ctrCounter(xk, n, buf, dst);
|
||||
xk.fill(0);
|
||||
n.fill(0);
|
||||
return out;
|
||||
}
|
||||
return {
|
||||
encrypt: (plaintext, dst) => processCtr(plaintext, dst),
|
||||
decrypt: (ciphertext, dst) => processCtr(ciphertext, dst),
|
||||
};
|
||||
});
|
||||
function validateBlockDecrypt(data) {
|
||||
(0, _assert_js_1.bytes)(data);
|
||||
if (data.length % BLOCK_SIZE !== 0) {
|
||||
throw new Error(`aes/(cbc-ecb).decrypt ciphertext should consist of blocks with size ${BLOCK_SIZE}`);
|
||||
}
|
||||
}
|
||||
function validateBlockEncrypt(plaintext, pcks5, dst) {
|
||||
let outLen = plaintext.length;
|
||||
const remaining = outLen % BLOCK_SIZE;
|
||||
if (!pcks5 && remaining !== 0)
|
||||
throw new Error('aec/(cbc-ecb): unpadded plaintext with disabled padding');
|
||||
const b = (0, utils_js_1.u32)(plaintext);
|
||||
if (pcks5) {
|
||||
let left = BLOCK_SIZE - remaining;
|
||||
if (!left)
|
||||
left = BLOCK_SIZE; // if no bytes left, create empty padding block
|
||||
outLen = outLen + left;
|
||||
}
|
||||
const out = getDst(outLen, dst);
|
||||
const o = (0, utils_js_1.u32)(out);
|
||||
return { b, o, out };
|
||||
}
|
||||
function validatePCKS(data, pcks5) {
|
||||
if (!pcks5)
|
||||
return data;
|
||||
const len = data.length;
|
||||
if (!len)
|
||||
throw new Error(`aes/pcks5: empty ciphertext not allowed`);
|
||||
const lastByte = data[len - 1];
|
||||
if (lastByte <= 0 || lastByte > 16)
|
||||
throw new Error(`aes/pcks5: wrong padding byte: ${lastByte}`);
|
||||
const out = data.subarray(0, -lastByte);
|
||||
for (let i = 0; i < lastByte; i++)
|
||||
if (data[len - i - 1] !== lastByte)
|
||||
throw new Error(`aes/pcks5: wrong padding`);
|
||||
return out;
|
||||
}
|
||||
function padPCKS(left) {
|
||||
const tmp = new Uint8Array(16);
|
||||
const tmp32 = (0, utils_js_1.u32)(tmp);
|
||||
tmp.set(left);
|
||||
const paddingByte = BLOCK_SIZE - left.length;
|
||||
for (let i = BLOCK_SIZE - paddingByte; i < BLOCK_SIZE; i++)
|
||||
tmp[i] = paddingByte;
|
||||
return tmp32;
|
||||
}
|
||||
/**
|
||||
* ECB: Electronic CodeBook. Simple deterministic replacement.
|
||||
* Dangerous: always map x to y. See [AES Penguin](https://words.filippo.io/the-ecb-penguin/).
|
||||
*/
|
||||
exports.ecb = (0, utils_js_1.wrapCipher)({ blockSize: 16 }, function ecb(key, opts = {}) {
|
||||
(0, _assert_js_1.bytes)(key);
|
||||
const pcks5 = !opts.disablePadding;
|
||||
return {
|
||||
encrypt: (plaintext, dst) => {
|
||||
(0, _assert_js_1.bytes)(plaintext);
|
||||
const { b, o, out: _out } = validateBlockEncrypt(plaintext, pcks5, dst);
|
||||
const xk = expandKeyLE(key);
|
||||
let i = 0;
|
||||
for (; i + 4 <= b.length;) {
|
||||
const { s0, s1, s2, s3 } = encrypt(xk, b[i + 0], b[i + 1], b[i + 2], b[i + 3]);
|
||||
(o[i++] = s0), (o[i++] = s1), (o[i++] = s2), (o[i++] = s3);
|
||||
}
|
||||
if (pcks5) {
|
||||
const tmp32 = padPCKS(plaintext.subarray(i * 4));
|
||||
const { s0, s1, s2, s3 } = encrypt(xk, tmp32[0], tmp32[1], tmp32[2], tmp32[3]);
|
||||
(o[i++] = s0), (o[i++] = s1), (o[i++] = s2), (o[i++] = s3);
|
||||
}
|
||||
xk.fill(0);
|
||||
return _out;
|
||||
},
|
||||
decrypt: (ciphertext, dst) => {
|
||||
validateBlockDecrypt(ciphertext);
|
||||
const xk = expandKeyDecLE(key);
|
||||
const out = getDst(ciphertext.length, dst);
|
||||
const b = (0, utils_js_1.u32)(ciphertext);
|
||||
const o = (0, utils_js_1.u32)(out);
|
||||
for (let i = 0; i + 4 <= b.length;) {
|
||||
const { s0, s1, s2, s3 } = decrypt(xk, b[i + 0], b[i + 1], b[i + 2], b[i + 3]);
|
||||
(o[i++] = s0), (o[i++] = s1), (o[i++] = s2), (o[i++] = s3);
|
||||
}
|
||||
xk.fill(0);
|
||||
return validatePCKS(out, pcks5);
|
||||
},
|
||||
};
|
||||
});
|
||||
/**
|
||||
* CBC: Cipher-Block-Chaining. Key is previous round’s block.
|
||||
* Fragile: needs proper padding. Unauthenticated: needs MAC.
|
||||
*/
|
||||
exports.cbc = (0, utils_js_1.wrapCipher)({ blockSize: 16, nonceLength: 16 }, function cbc(key, iv, opts = {}) {
|
||||
(0, _assert_js_1.bytes)(key);
|
||||
(0, _assert_js_1.bytes)(iv, 16);
|
||||
const pcks5 = !opts.disablePadding;
|
||||
return {
|
||||
encrypt: (plaintext, dst) => {
|
||||
const xk = expandKeyLE(key);
|
||||
const { b, o, out: _out } = validateBlockEncrypt(plaintext, pcks5, dst);
|
||||
const n32 = (0, utils_js_1.u32)(iv);
|
||||
// prettier-ignore
|
||||
let s0 = n32[0], s1 = n32[1], s2 = n32[2], s3 = n32[3];
|
||||
let i = 0;
|
||||
for (; i + 4 <= b.length;) {
|
||||
(s0 ^= b[i + 0]), (s1 ^= b[i + 1]), (s2 ^= b[i + 2]), (s3 ^= b[i + 3]);
|
||||
({ s0, s1, s2, s3 } = encrypt(xk, s0, s1, s2, s3));
|
||||
(o[i++] = s0), (o[i++] = s1), (o[i++] = s2), (o[i++] = s3);
|
||||
}
|
||||
if (pcks5) {
|
||||
const tmp32 = padPCKS(plaintext.subarray(i * 4));
|
||||
(s0 ^= tmp32[0]), (s1 ^= tmp32[1]), (s2 ^= tmp32[2]), (s3 ^= tmp32[3]);
|
||||
({ s0, s1, s2, s3 } = encrypt(xk, s0, s1, s2, s3));
|
||||
(o[i++] = s0), (o[i++] = s1), (o[i++] = s2), (o[i++] = s3);
|
||||
}
|
||||
xk.fill(0);
|
||||
return _out;
|
||||
},
|
||||
decrypt: (ciphertext, dst) => {
|
||||
validateBlockDecrypt(ciphertext);
|
||||
const xk = expandKeyDecLE(key);
|
||||
const n32 = (0, utils_js_1.u32)(iv);
|
||||
const out = getDst(ciphertext.length, dst);
|
||||
const b = (0, utils_js_1.u32)(ciphertext);
|
||||
const o = (0, utils_js_1.u32)(out);
|
||||
// prettier-ignore
|
||||
let s0 = n32[0], s1 = n32[1], s2 = n32[2], s3 = n32[3];
|
||||
for (let i = 0; i + 4 <= b.length;) {
|
||||
// prettier-ignore
|
||||
const ps0 = s0, ps1 = s1, ps2 = s2, ps3 = s3;
|
||||
(s0 = b[i + 0]), (s1 = b[i + 1]), (s2 = b[i + 2]), (s3 = b[i + 3]);
|
||||
const { s0: o0, s1: o1, s2: o2, s3: o3 } = decrypt(xk, s0, s1, s2, s3);
|
||||
(o[i++] = o0 ^ ps0), (o[i++] = o1 ^ ps1), (o[i++] = o2 ^ ps2), (o[i++] = o3 ^ ps3);
|
||||
}
|
||||
xk.fill(0);
|
||||
return validatePCKS(out, pcks5);
|
||||
},
|
||||
};
|
||||
});
|
||||
/**
|
||||
* CFB: Cipher Feedback Mode. The input for the block cipher is the previous cipher output.
|
||||
* Unauthenticated: needs MAC.
|
||||
*/
|
||||
exports.cfb = (0, utils_js_1.wrapCipher)({ blockSize: 16, nonceLength: 16 }, function cfb(key, iv) {
|
||||
(0, _assert_js_1.bytes)(key);
|
||||
(0, _assert_js_1.bytes)(iv, 16);
|
||||
function processCfb(src, isEncrypt, dst) {
|
||||
const xk = expandKeyLE(key);
|
||||
const srcLen = src.length;
|
||||
dst = getDst(srcLen, dst);
|
||||
const src32 = (0, utils_js_1.u32)(src);
|
||||
const dst32 = (0, utils_js_1.u32)(dst);
|
||||
const next32 = isEncrypt ? dst32 : src32;
|
||||
const n32 = (0, utils_js_1.u32)(iv);
|
||||
// prettier-ignore
|
||||
let s0 = n32[0], s1 = n32[1], s2 = n32[2], s3 = n32[3];
|
||||
for (let i = 0; i + 4 <= src32.length;) {
|
||||
const { s0: e0, s1: e1, s2: e2, s3: e3 } = encrypt(xk, s0, s1, s2, s3);
|
||||
dst32[i + 0] = src32[i + 0] ^ e0;
|
||||
dst32[i + 1] = src32[i + 1] ^ e1;
|
||||
dst32[i + 2] = src32[i + 2] ^ e2;
|
||||
dst32[i + 3] = src32[i + 3] ^ e3;
|
||||
(s0 = next32[i++]), (s1 = next32[i++]), (s2 = next32[i++]), (s3 = next32[i++]);
|
||||
}
|
||||
// leftovers (less than block)
|
||||
const start = BLOCK_SIZE * Math.floor(src32.length / BLOCK_SIZE32);
|
||||
if (start < srcLen) {
|
||||
({ s0, s1, s2, s3 } = encrypt(xk, s0, s1, s2, s3));
|
||||
const buf = (0, utils_js_1.u8)(new Uint32Array([s0, s1, s2, s3]));
|
||||
for (let i = start, pos = 0; i < srcLen; i++, pos++)
|
||||
dst[i] = src[i] ^ buf[pos];
|
||||
buf.fill(0);
|
||||
}
|
||||
xk.fill(0);
|
||||
return dst;
|
||||
}
|
||||
return {
|
||||
encrypt: (plaintext, dst) => processCfb(plaintext, true, dst),
|
||||
decrypt: (ciphertext, dst) => processCfb(ciphertext, false, dst),
|
||||
};
|
||||
});
|
||||
// TODO: merge with chacha, however gcm has bitLen while chacha has byteLen
|
||||
function computeTag(fn, isLE, key, data, AAD) {
|
||||
const h = fn.create(key, data.length + (AAD?.length || 0));
|
||||
if (AAD)
|
||||
h.update(AAD);
|
||||
h.update(data);
|
||||
const num = new Uint8Array(16);
|
||||
const view = (0, utils_js_1.createView)(num);
|
||||
if (AAD)
|
||||
(0, utils_js_1.setBigUint64)(view, 0, BigInt(AAD.length * 8), isLE);
|
||||
(0, utils_js_1.setBigUint64)(view, 8, BigInt(data.length * 8), isLE);
|
||||
h.update(num);
|
||||
return h.digest();
|
||||
}
|
||||
/**
|
||||
* GCM: Galois/Counter Mode.
|
||||
* Good, modern version of CTR, parallel, with MAC.
|
||||
* Be careful: MACs can be forged.
|
||||
*/
|
||||
exports.gcm = (0, utils_js_1.wrapCipher)({ blockSize: 16, nonceLength: 12, tagLength: 16 }, function gcm(key, nonce, AAD) {
|
||||
(0, _assert_js_1.bytes)(nonce);
|
||||
// Nonce can be pretty much anything (even 1 byte). But smaller nonces less secure.
|
||||
if (nonce.length === 0)
|
||||
throw new Error('aes/gcm: empty nonce');
|
||||
const tagLength = 16;
|
||||
function _computeTag(authKey, tagMask, data) {
|
||||
const tag = computeTag(_polyval_js_1.ghash, false, authKey, data, AAD);
|
||||
for (let i = 0; i < tagMask.length; i++)
|
||||
tag[i] ^= tagMask[i];
|
||||
return tag;
|
||||
}
|
||||
function deriveKeys() {
|
||||
const xk = expandKeyLE(key);
|
||||
const authKey = EMPTY_BLOCK.slice();
|
||||
const counter = EMPTY_BLOCK.slice();
|
||||
ctr32(xk, false, counter, counter, authKey);
|
||||
if (nonce.length === 12) {
|
||||
counter.set(nonce);
|
||||
}
|
||||
else {
|
||||
// Spec (NIST 800-38d) supports variable size nonce.
|
||||
// Not supported for now, but can be useful.
|
||||
const nonceLen = EMPTY_BLOCK.slice();
|
||||
const view = (0, utils_js_1.createView)(nonceLen);
|
||||
(0, utils_js_1.setBigUint64)(view, 8, BigInt(nonce.length * 8), false);
|
||||
// ghash(nonce || u64be(0) || u64be(nonceLen*8))
|
||||
_polyval_js_1.ghash.create(authKey).update(nonce).update(nonceLen).digestInto(counter);
|
||||
}
|
||||
const tagMask = ctr32(xk, false, counter, EMPTY_BLOCK);
|
||||
return { xk, authKey, counter, tagMask };
|
||||
}
|
||||
return {
|
||||
encrypt: (plaintext) => {
|
||||
(0, _assert_js_1.bytes)(plaintext);
|
||||
const { xk, authKey, counter, tagMask } = deriveKeys();
|
||||
const out = new Uint8Array(plaintext.length + tagLength);
|
||||
ctr32(xk, false, counter, plaintext, out);
|
||||
const tag = _computeTag(authKey, tagMask, out.subarray(0, out.length - tagLength));
|
||||
out.set(tag, plaintext.length);
|
||||
xk.fill(0);
|
||||
return out;
|
||||
},
|
||||
decrypt: (ciphertext) => {
|
||||
(0, _assert_js_1.bytes)(ciphertext);
|
||||
if (ciphertext.length < tagLength)
|
||||
throw new Error(`aes/gcm: ciphertext less than tagLen (${tagLength})`);
|
||||
const { xk, authKey, counter, tagMask } = deriveKeys();
|
||||
const data = ciphertext.subarray(0, -tagLength);
|
||||
const passedTag = ciphertext.subarray(-tagLength);
|
||||
const tag = _computeTag(authKey, tagMask, data);
|
||||
if (!(0, utils_js_1.equalBytes)(tag, passedTag))
|
||||
throw new Error('aes/gcm: invalid ghash tag');
|
||||
const out = ctr32(xk, false, counter, data);
|
||||
authKey.fill(0);
|
||||
tagMask.fill(0);
|
||||
xk.fill(0);
|
||||
return out;
|
||||
},
|
||||
};
|
||||
});
|
||||
const limit = (name, min, max) => (value) => {
|
||||
if (!Number.isSafeInteger(value) || min > value || value > max)
|
||||
throw new Error(`${name}: invalid value=${value}, must be [${min}..${max}]`);
|
||||
};
|
||||
/**
|
||||
* AES-GCM-SIV: classic AES-GCM with nonce-misuse resistance.
|
||||
* Guarantees that, when a nonce is repeated, the only security loss is that identical
|
||||
* plaintexts will produce identical ciphertexts.
|
||||
* RFC 8452, https://datatracker.ietf.org/doc/html/rfc8452
|
||||
*/
|
||||
exports.siv = (0, utils_js_1.wrapCipher)({ blockSize: 16, nonceLength: 12, tagLength: 16 }, function siv(key, nonce, AAD) {
|
||||
const tagLength = 16;
|
||||
// From RFC 8452: Section 6
|
||||
const AAD_LIMIT = limit('AAD', 0, 2 ** 36);
|
||||
const PLAIN_LIMIT = limit('plaintext', 0, 2 ** 36);
|
||||
const NONCE_LIMIT = limit('nonce', 12, 12);
|
||||
const CIPHER_LIMIT = limit('ciphertext', 16, 2 ** 36 + 16);
|
||||
(0, _assert_js_1.bytes)(nonce);
|
||||
NONCE_LIMIT(nonce.length);
|
||||
if (AAD) {
|
||||
(0, _assert_js_1.bytes)(AAD);
|
||||
AAD_LIMIT(AAD.length);
|
||||
}
|
||||
function deriveKeys() {
|
||||
const len = key.length;
|
||||
if (len !== 16 && len !== 24 && len !== 32)
|
||||
throw new Error(`key length must be 16, 24 or 32 bytes, got: ${len} bytes`);
|
||||
const xk = expandKeyLE(key);
|
||||
const encKey = new Uint8Array(len);
|
||||
const authKey = new Uint8Array(16);
|
||||
const n32 = (0, utils_js_1.u32)(nonce);
|
||||
// prettier-ignore
|
||||
let s0 = 0, s1 = n32[0], s2 = n32[1], s3 = n32[2];
|
||||
let counter = 0;
|
||||
for (const derivedKey of [authKey, encKey].map(utils_js_1.u32)) {
|
||||
const d32 = (0, utils_js_1.u32)(derivedKey);
|
||||
for (let i = 0; i < d32.length; i += 2) {
|
||||
// aes(u32le(0) || nonce)[:8] || aes(u32le(1) || nonce)[:8] ...
|
||||
const { s0: o0, s1: o1 } = encrypt(xk, s0, s1, s2, s3);
|
||||
d32[i + 0] = o0;
|
||||
d32[i + 1] = o1;
|
||||
s0 = ++counter; // increment counter inside state
|
||||
}
|
||||
}
|
||||
xk.fill(0);
|
||||
return { authKey, encKey: expandKeyLE(encKey) };
|
||||
}
|
||||
function _computeTag(encKey, authKey, data) {
|
||||
const tag = computeTag(_polyval_js_1.polyval, true, authKey, data, AAD);
|
||||
// Compute the expected tag by XORing S_s and the nonce, clearing the
|
||||
// most significant bit of the last byte and encrypting with the
|
||||
// message-encryption key.
|
||||
for (let i = 0; i < 12; i++)
|
||||
tag[i] ^= nonce[i];
|
||||
tag[15] &= 0x7f; // Clear the highest bit
|
||||
// encrypt tag as block
|
||||
const t32 = (0, utils_js_1.u32)(tag);
|
||||
// prettier-ignore
|
||||
let s0 = t32[0], s1 = t32[1], s2 = t32[2], s3 = t32[3];
|
||||
({ s0, s1, s2, s3 } = encrypt(encKey, s0, s1, s2, s3));
|
||||
(t32[0] = s0), (t32[1] = s1), (t32[2] = s2), (t32[3] = s3);
|
||||
return tag;
|
||||
}
|
||||
// actual decrypt/encrypt of message.
|
||||
function processSiv(encKey, tag, input) {
|
||||
let block = tag.slice();
|
||||
block[15] |= 0x80; // Force highest bit
|
||||
return ctr32(encKey, true, block, input);
|
||||
}
|
||||
return {
|
||||
encrypt: (plaintext) => {
|
||||
(0, _assert_js_1.bytes)(plaintext);
|
||||
PLAIN_LIMIT(plaintext.length);
|
||||
const { encKey, authKey } = deriveKeys();
|
||||
const tag = _computeTag(encKey, authKey, plaintext);
|
||||
const out = new Uint8Array(plaintext.length + tagLength);
|
||||
out.set(tag, plaintext.length);
|
||||
out.set(processSiv(encKey, tag, plaintext));
|
||||
encKey.fill(0);
|
||||
authKey.fill(0);
|
||||
return out;
|
||||
},
|
||||
decrypt: (ciphertext) => {
|
||||
(0, _assert_js_1.bytes)(ciphertext);
|
||||
CIPHER_LIMIT(ciphertext.length);
|
||||
const tag = ciphertext.subarray(-tagLength);
|
||||
const { encKey, authKey } = deriveKeys();
|
||||
const plaintext = processSiv(encKey, tag, ciphertext.subarray(0, -tagLength));
|
||||
const expectedTag = _computeTag(encKey, authKey, plaintext);
|
||||
encKey.fill(0);
|
||||
authKey.fill(0);
|
||||
if (!(0, utils_js_1.equalBytes)(tag, expectedTag))
|
||||
throw new Error('invalid polyval tag');
|
||||
return plaintext;
|
||||
},
|
||||
};
|
||||
});
|
||||
function isBytes32(a) {
|
||||
return (a != null &&
|
||||
typeof a === 'object' &&
|
||||
(a instanceof Uint32Array || a.constructor.name === 'Uint32Array'));
|
||||
}
|
||||
function encryptBlock(xk, block) {
|
||||
(0, _assert_js_1.bytes)(block, 16);
|
||||
if (!isBytes32(xk))
|
||||
throw new Error('_encryptBlock accepts result of expandKeyLE');
|
||||
const b32 = (0, utils_js_1.u32)(block);
|
||||
let { s0, s1, s2, s3 } = encrypt(xk, b32[0], b32[1], b32[2], b32[3]);
|
||||
(b32[0] = s0), (b32[1] = s1), (b32[2] = s2), (b32[3] = s3);
|
||||
return block;
|
||||
}
|
||||
function decryptBlock(xk, block) {
|
||||
(0, _assert_js_1.bytes)(block, 16);
|
||||
if (!isBytes32(xk))
|
||||
throw new Error('_decryptBlock accepts result of expandKeyLE');
|
||||
const b32 = (0, utils_js_1.u32)(block);
|
||||
let { s0, s1, s2, s3 } = decrypt(xk, b32[0], b32[1], b32[2], b32[3]);
|
||||
(b32[0] = s0), (b32[1] = s1), (b32[2] = s2), (b32[3] = s3);
|
||||
return block;
|
||||
}
|
||||
// Highly unsafe private functions for implementing new modes or ciphers based on AES
|
||||
// Can change at any time, no API guarantees
|
||||
exports.unsafe = {
|
||||
expandKeyLE,
|
||||
expandKeyDecLE,
|
||||
encrypt,
|
||||
decrypt,
|
||||
encryptBlock,
|
||||
decryptBlock,
|
||||
ctrCounter,
|
||||
ctr32,
|
||||
};
|
||||
//# sourceMappingURL=aes.js.map
|
||||
1
thrower_daemon/node_modules/@noble/ciphers/aes.js.map
generated
vendored
Normal file
1
thrower_daemon/node_modules/@noble/ciphers/aes.js.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
61
thrower_daemon/node_modules/@noble/ciphers/chacha.d.ts
generated
vendored
Normal file
61
thrower_daemon/node_modules/@noble/ciphers/chacha.d.ts
generated
vendored
Normal file
@@ -0,0 +1,61 @@
|
||||
import { CipherWithOutput, XorStream } from './utils.js';
|
||||
/**
|
||||
* hchacha helper method, used primarily in xchacha, to hash
|
||||
* key and nonce into key' and nonce'.
|
||||
* Same as chachaCore, but there doesn't seem to be a way to move the block
|
||||
* out without 25% performance hit.
|
||||
*/
|
||||
export declare function hchacha(s: Uint32Array, k: Uint32Array, i: Uint32Array, o32: Uint32Array): void;
|
||||
/**
|
||||
* Original, non-RFC chacha20 from DJB. 8-byte nonce, 8-byte counter.
|
||||
*/
|
||||
export declare const chacha20orig: XorStream;
|
||||
/**
|
||||
* ChaCha stream cipher. Conforms to RFC 8439 (IETF, TLS). 12-byte nonce, 4-byte counter.
|
||||
* With 12-byte nonce, it's not safe to use fill it with random (CSPRNG), due to collision chance.
|
||||
*/
|
||||
export declare const chacha20: XorStream;
|
||||
/**
|
||||
* XChaCha eXtended-nonce ChaCha. 24-byte nonce.
|
||||
* With 24-byte nonce, it's safe to use fill it with random (CSPRNG).
|
||||
* https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-xchacha
|
||||
*/
|
||||
export declare const xchacha20: XorStream;
|
||||
/**
|
||||
* Reduced 8-round chacha, described in original paper.
|
||||
*/
|
||||
export declare const chacha8: XorStream;
|
||||
/**
|
||||
* Reduced 12-round chacha, described in original paper.
|
||||
*/
|
||||
export declare const chacha12: XorStream;
|
||||
/**
|
||||
* AEAD algorithm from RFC 8439.
|
||||
* Salsa20 and chacha (RFC 8439) use poly1305 differently.
|
||||
* We could have composed them similar to:
|
||||
* https://github.com/paulmillr/scure-base/blob/b266c73dde977b1dd7ef40ef7a23cc15aab526b3/index.ts#L250
|
||||
* But it's hard because of authKey:
|
||||
* In salsa20, authKey changes position in salsa stream.
|
||||
* In chacha, authKey can't be computed inside computeTag, it modifies the counter.
|
||||
*/
|
||||
export declare const _poly1305_aead: (xorStream: XorStream) => (key: Uint8Array, nonce: Uint8Array, AAD?: Uint8Array) => CipherWithOutput;
|
||||
/**
|
||||
* ChaCha20-Poly1305 from RFC 8439.
|
||||
* With 12-byte nonce, it's not safe to use fill it with random (CSPRNG), due to collision chance.
|
||||
*/
|
||||
export declare const chacha20poly1305: ((key: Uint8Array, nonce: Uint8Array, AAD?: Uint8Array) => CipherWithOutput) & {
|
||||
blockSize: number;
|
||||
nonceLength: number;
|
||||
tagLength: number;
|
||||
};
|
||||
/**
|
||||
* XChaCha20-Poly1305 extended-nonce chacha.
|
||||
* https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-xchacha
|
||||
* With 24-byte nonce, it's safe to use fill it with random (CSPRNG).
|
||||
*/
|
||||
export declare const xchacha20poly1305: ((key: Uint8Array, nonce: Uint8Array, AAD?: Uint8Array) => CipherWithOutput) & {
|
||||
blockSize: number;
|
||||
nonceLength: number;
|
||||
tagLength: number;
|
||||
};
|
||||
//# sourceMappingURL=chacha.d.ts.map
|
||||
1
thrower_daemon/node_modules/@noble/ciphers/chacha.d.ts.map
generated
vendored
Normal file
1
thrower_daemon/node_modules/@noble/ciphers/chacha.d.ts.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"chacha.d.ts","sourceRoot":"","sources":["src/chacha.ts"],"names":[],"mappings":"AACA,OAAO,EACO,gBAAgB,EAAE,SAAS,EACxC,MAAM,YAAY,CAAC;AA6EpB;;;;;GAKG;AAEH,wBAAgB,OAAO,CACrB,CAAC,EAAE,WAAW,EAAE,CAAC,EAAE,WAAW,EAAE,CAAC,EAAE,WAAW,EAAE,GAAG,EAAE,WAAW,QAoDjE;AACD;;GAEG;AACH,eAAO,MAAM,YAAY,WAIvB,CAAC;AACH;;;GAGG;AACH,eAAO,MAAM,QAAQ,WAInB,CAAC;AAEH;;;;GAIG;AACH,eAAO,MAAM,SAAS,WAKpB,CAAC;AAEH;;GAEG;AACH,eAAO,MAAM,OAAO,WAIlB,CAAC;AAEH;;GAEG;AACH,eAAO,MAAM,QAAQ,WAInB,CAAC;AAgCH;;;;;;;;GAQG;AACH,eAAO,MAAM,cAAc,cACb,SAAS,WACf,UAAU,SAAS,UAAU,QAAQ,UAAU,KAAG,gBAoCvD,CAAC;AAEJ;;;GAGG;AACH,eAAO,MAAM,gBAAgB,SA1CrB,UAAU,SAAS,UAAU,QAAQ,UAAU,KAAG,gBAAgB;;;;CA6CzE,CAAC;AACF;;;;GAIG;AACH,eAAO,MAAM,iBAAiB,SAnDtB,UAAU,SAAS,UAAU,QAAQ,UAAU,KAAG,gBAAgB;;;;CAsDzE,CAAC"}
|
||||
323
thrower_daemon/node_modules/@noble/ciphers/chacha.js
generated
vendored
Normal file
323
thrower_daemon/node_modules/@noble/ciphers/chacha.js
generated
vendored
Normal file
@@ -0,0 +1,323 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.xchacha20poly1305 = exports.chacha20poly1305 = exports._poly1305_aead = exports.chacha12 = exports.chacha8 = exports.xchacha20 = exports.chacha20 = exports.chacha20orig = exports.hchacha = void 0;
|
||||
// prettier-ignore
|
||||
const utils_js_1 = require("./utils.js");
|
||||
const _poly1305_js_1 = require("./_poly1305.js");
|
||||
const _arx_js_1 = require("./_arx.js");
|
||||
const _assert_js_1 = require("./_assert.js");
|
||||
// ChaCha20 stream cipher was released in 2008. ChaCha aims to increase
|
||||
// the diffusion per round, but had slightly less cryptanalysis.
|
||||
// https://cr.yp.to/chacha.html, http://cr.yp.to/chacha/chacha-20080128.pdf
|
||||
/**
|
||||
* ChaCha core function.
|
||||
*/
|
||||
// prettier-ignore
|
||||
function chachaCore(s, k, n, out, cnt, rounds = 20) {
|
||||
let y00 = s[0], y01 = s[1], y02 = s[2], y03 = s[3], // "expa" "nd 3" "2-by" "te k"
|
||||
y04 = k[0], y05 = k[1], y06 = k[2], y07 = k[3], // Key Key Key Key
|
||||
y08 = k[4], y09 = k[5], y10 = k[6], y11 = k[7], // Key Key Key Key
|
||||
y12 = cnt, y13 = n[0], y14 = n[1], y15 = n[2]; // Counter Counter Nonce Nonce
|
||||
// Save state to temporary variables
|
||||
let x00 = y00, x01 = y01, x02 = y02, x03 = y03, x04 = y04, x05 = y05, x06 = y06, x07 = y07, x08 = y08, x09 = y09, x10 = y10, x11 = y11, x12 = y12, x13 = y13, x14 = y14, x15 = y15;
|
||||
for (let r = 0; r < rounds; r += 2) {
|
||||
x00 = (x00 + x04) | 0;
|
||||
x12 = (0, _arx_js_1.rotl)(x12 ^ x00, 16);
|
||||
x08 = (x08 + x12) | 0;
|
||||
x04 = (0, _arx_js_1.rotl)(x04 ^ x08, 12);
|
||||
x00 = (x00 + x04) | 0;
|
||||
x12 = (0, _arx_js_1.rotl)(x12 ^ x00, 8);
|
||||
x08 = (x08 + x12) | 0;
|
||||
x04 = (0, _arx_js_1.rotl)(x04 ^ x08, 7);
|
||||
x01 = (x01 + x05) | 0;
|
||||
x13 = (0, _arx_js_1.rotl)(x13 ^ x01, 16);
|
||||
x09 = (x09 + x13) | 0;
|
||||
x05 = (0, _arx_js_1.rotl)(x05 ^ x09, 12);
|
||||
x01 = (x01 + x05) | 0;
|
||||
x13 = (0, _arx_js_1.rotl)(x13 ^ x01, 8);
|
||||
x09 = (x09 + x13) | 0;
|
||||
x05 = (0, _arx_js_1.rotl)(x05 ^ x09, 7);
|
||||
x02 = (x02 + x06) | 0;
|
||||
x14 = (0, _arx_js_1.rotl)(x14 ^ x02, 16);
|
||||
x10 = (x10 + x14) | 0;
|
||||
x06 = (0, _arx_js_1.rotl)(x06 ^ x10, 12);
|
||||
x02 = (x02 + x06) | 0;
|
||||
x14 = (0, _arx_js_1.rotl)(x14 ^ x02, 8);
|
||||
x10 = (x10 + x14) | 0;
|
||||
x06 = (0, _arx_js_1.rotl)(x06 ^ x10, 7);
|
||||
x03 = (x03 + x07) | 0;
|
||||
x15 = (0, _arx_js_1.rotl)(x15 ^ x03, 16);
|
||||
x11 = (x11 + x15) | 0;
|
||||
x07 = (0, _arx_js_1.rotl)(x07 ^ x11, 12);
|
||||
x03 = (x03 + x07) | 0;
|
||||
x15 = (0, _arx_js_1.rotl)(x15 ^ x03, 8);
|
||||
x11 = (x11 + x15) | 0;
|
||||
x07 = (0, _arx_js_1.rotl)(x07 ^ x11, 7);
|
||||
x00 = (x00 + x05) | 0;
|
||||
x15 = (0, _arx_js_1.rotl)(x15 ^ x00, 16);
|
||||
x10 = (x10 + x15) | 0;
|
||||
x05 = (0, _arx_js_1.rotl)(x05 ^ x10, 12);
|
||||
x00 = (x00 + x05) | 0;
|
||||
x15 = (0, _arx_js_1.rotl)(x15 ^ x00, 8);
|
||||
x10 = (x10 + x15) | 0;
|
||||
x05 = (0, _arx_js_1.rotl)(x05 ^ x10, 7);
|
||||
x01 = (x01 + x06) | 0;
|
||||
x12 = (0, _arx_js_1.rotl)(x12 ^ x01, 16);
|
||||
x11 = (x11 + x12) | 0;
|
||||
x06 = (0, _arx_js_1.rotl)(x06 ^ x11, 12);
|
||||
x01 = (x01 + x06) | 0;
|
||||
x12 = (0, _arx_js_1.rotl)(x12 ^ x01, 8);
|
||||
x11 = (x11 + x12) | 0;
|
||||
x06 = (0, _arx_js_1.rotl)(x06 ^ x11, 7);
|
||||
x02 = (x02 + x07) | 0;
|
||||
x13 = (0, _arx_js_1.rotl)(x13 ^ x02, 16);
|
||||
x08 = (x08 + x13) | 0;
|
||||
x07 = (0, _arx_js_1.rotl)(x07 ^ x08, 12);
|
||||
x02 = (x02 + x07) | 0;
|
||||
x13 = (0, _arx_js_1.rotl)(x13 ^ x02, 8);
|
||||
x08 = (x08 + x13) | 0;
|
||||
x07 = (0, _arx_js_1.rotl)(x07 ^ x08, 7);
|
||||
x03 = (x03 + x04) | 0;
|
||||
x14 = (0, _arx_js_1.rotl)(x14 ^ x03, 16);
|
||||
x09 = (x09 + x14) | 0;
|
||||
x04 = (0, _arx_js_1.rotl)(x04 ^ x09, 12);
|
||||
x03 = (x03 + x04) | 0;
|
||||
x14 = (0, _arx_js_1.rotl)(x14 ^ x03, 8);
|
||||
x09 = (x09 + x14) | 0;
|
||||
x04 = (0, _arx_js_1.rotl)(x04 ^ x09, 7);
|
||||
}
|
||||
// Write output
|
||||
let oi = 0;
|
||||
out[oi++] = (y00 + x00) | 0;
|
||||
out[oi++] = (y01 + x01) | 0;
|
||||
out[oi++] = (y02 + x02) | 0;
|
||||
out[oi++] = (y03 + x03) | 0;
|
||||
out[oi++] = (y04 + x04) | 0;
|
||||
out[oi++] = (y05 + x05) | 0;
|
||||
out[oi++] = (y06 + x06) | 0;
|
||||
out[oi++] = (y07 + x07) | 0;
|
||||
out[oi++] = (y08 + x08) | 0;
|
||||
out[oi++] = (y09 + x09) | 0;
|
||||
out[oi++] = (y10 + x10) | 0;
|
||||
out[oi++] = (y11 + x11) | 0;
|
||||
out[oi++] = (y12 + x12) | 0;
|
||||
out[oi++] = (y13 + x13) | 0;
|
||||
out[oi++] = (y14 + x14) | 0;
|
||||
out[oi++] = (y15 + x15) | 0;
|
||||
}
|
||||
/**
|
||||
* hchacha helper method, used primarily in xchacha, to hash
|
||||
* key and nonce into key' and nonce'.
|
||||
* Same as chachaCore, but there doesn't seem to be a way to move the block
|
||||
* out without 25% performance hit.
|
||||
*/
|
||||
// prettier-ignore
|
||||
function hchacha(s, k, i, o32) {
|
||||
let x00 = s[0], x01 = s[1], x02 = s[2], x03 = s[3], x04 = k[0], x05 = k[1], x06 = k[2], x07 = k[3], x08 = k[4], x09 = k[5], x10 = k[6], x11 = k[7], x12 = i[0], x13 = i[1], x14 = i[2], x15 = i[3];
|
||||
for (let r = 0; r < 20; r += 2) {
|
||||
x00 = (x00 + x04) | 0;
|
||||
x12 = (0, _arx_js_1.rotl)(x12 ^ x00, 16);
|
||||
x08 = (x08 + x12) | 0;
|
||||
x04 = (0, _arx_js_1.rotl)(x04 ^ x08, 12);
|
||||
x00 = (x00 + x04) | 0;
|
||||
x12 = (0, _arx_js_1.rotl)(x12 ^ x00, 8);
|
||||
x08 = (x08 + x12) | 0;
|
||||
x04 = (0, _arx_js_1.rotl)(x04 ^ x08, 7);
|
||||
x01 = (x01 + x05) | 0;
|
||||
x13 = (0, _arx_js_1.rotl)(x13 ^ x01, 16);
|
||||
x09 = (x09 + x13) | 0;
|
||||
x05 = (0, _arx_js_1.rotl)(x05 ^ x09, 12);
|
||||
x01 = (x01 + x05) | 0;
|
||||
x13 = (0, _arx_js_1.rotl)(x13 ^ x01, 8);
|
||||
x09 = (x09 + x13) | 0;
|
||||
x05 = (0, _arx_js_1.rotl)(x05 ^ x09, 7);
|
||||
x02 = (x02 + x06) | 0;
|
||||
x14 = (0, _arx_js_1.rotl)(x14 ^ x02, 16);
|
||||
x10 = (x10 + x14) | 0;
|
||||
x06 = (0, _arx_js_1.rotl)(x06 ^ x10, 12);
|
||||
x02 = (x02 + x06) | 0;
|
||||
x14 = (0, _arx_js_1.rotl)(x14 ^ x02, 8);
|
||||
x10 = (x10 + x14) | 0;
|
||||
x06 = (0, _arx_js_1.rotl)(x06 ^ x10, 7);
|
||||
x03 = (x03 + x07) | 0;
|
||||
x15 = (0, _arx_js_1.rotl)(x15 ^ x03, 16);
|
||||
x11 = (x11 + x15) | 0;
|
||||
x07 = (0, _arx_js_1.rotl)(x07 ^ x11, 12);
|
||||
x03 = (x03 + x07) | 0;
|
||||
x15 = (0, _arx_js_1.rotl)(x15 ^ x03, 8);
|
||||
x11 = (x11 + x15) | 0;
|
||||
x07 = (0, _arx_js_1.rotl)(x07 ^ x11, 7);
|
||||
x00 = (x00 + x05) | 0;
|
||||
x15 = (0, _arx_js_1.rotl)(x15 ^ x00, 16);
|
||||
x10 = (x10 + x15) | 0;
|
||||
x05 = (0, _arx_js_1.rotl)(x05 ^ x10, 12);
|
||||
x00 = (x00 + x05) | 0;
|
||||
x15 = (0, _arx_js_1.rotl)(x15 ^ x00, 8);
|
||||
x10 = (x10 + x15) | 0;
|
||||
x05 = (0, _arx_js_1.rotl)(x05 ^ x10, 7);
|
||||
x01 = (x01 + x06) | 0;
|
||||
x12 = (0, _arx_js_1.rotl)(x12 ^ x01, 16);
|
||||
x11 = (x11 + x12) | 0;
|
||||
x06 = (0, _arx_js_1.rotl)(x06 ^ x11, 12);
|
||||
x01 = (x01 + x06) | 0;
|
||||
x12 = (0, _arx_js_1.rotl)(x12 ^ x01, 8);
|
||||
x11 = (x11 + x12) | 0;
|
||||
x06 = (0, _arx_js_1.rotl)(x06 ^ x11, 7);
|
||||
x02 = (x02 + x07) | 0;
|
||||
x13 = (0, _arx_js_1.rotl)(x13 ^ x02, 16);
|
||||
x08 = (x08 + x13) | 0;
|
||||
x07 = (0, _arx_js_1.rotl)(x07 ^ x08, 12);
|
||||
x02 = (x02 + x07) | 0;
|
||||
x13 = (0, _arx_js_1.rotl)(x13 ^ x02, 8);
|
||||
x08 = (x08 + x13) | 0;
|
||||
x07 = (0, _arx_js_1.rotl)(x07 ^ x08, 7);
|
||||
x03 = (x03 + x04) | 0;
|
||||
x14 = (0, _arx_js_1.rotl)(x14 ^ x03, 16);
|
||||
x09 = (x09 + x14) | 0;
|
||||
x04 = (0, _arx_js_1.rotl)(x04 ^ x09, 12);
|
||||
x03 = (x03 + x04) | 0;
|
||||
x14 = (0, _arx_js_1.rotl)(x14 ^ x03, 8);
|
||||
x09 = (x09 + x14) | 0;
|
||||
x04 = (0, _arx_js_1.rotl)(x04 ^ x09, 7);
|
||||
}
|
||||
let oi = 0;
|
||||
o32[oi++] = x00;
|
||||
o32[oi++] = x01;
|
||||
o32[oi++] = x02;
|
||||
o32[oi++] = x03;
|
||||
o32[oi++] = x12;
|
||||
o32[oi++] = x13;
|
||||
o32[oi++] = x14;
|
||||
o32[oi++] = x15;
|
||||
}
|
||||
exports.hchacha = hchacha;
|
||||
/**
|
||||
* Original, non-RFC chacha20 from DJB. 8-byte nonce, 8-byte counter.
|
||||
*/
|
||||
exports.chacha20orig = (0, _arx_js_1.createCipher)(chachaCore, {
|
||||
counterRight: false,
|
||||
counterLength: 8,
|
||||
allowShortKeys: true,
|
||||
});
|
||||
/**
|
||||
* ChaCha stream cipher. Conforms to RFC 8439 (IETF, TLS). 12-byte nonce, 4-byte counter.
|
||||
* With 12-byte nonce, it's not safe to use fill it with random (CSPRNG), due to collision chance.
|
||||
*/
|
||||
exports.chacha20 = (0, _arx_js_1.createCipher)(chachaCore, {
|
||||
counterRight: false,
|
||||
counterLength: 4,
|
||||
allowShortKeys: false,
|
||||
});
|
||||
/**
|
||||
* XChaCha eXtended-nonce ChaCha. 24-byte nonce.
|
||||
* With 24-byte nonce, it's safe to use fill it with random (CSPRNG).
|
||||
* https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-xchacha
|
||||
*/
|
||||
exports.xchacha20 = (0, _arx_js_1.createCipher)(chachaCore, {
|
||||
counterRight: false,
|
||||
counterLength: 8,
|
||||
extendNonceFn: hchacha,
|
||||
allowShortKeys: false,
|
||||
});
|
||||
/**
|
||||
* Reduced 8-round chacha, described in original paper.
|
||||
*/
|
||||
exports.chacha8 = (0, _arx_js_1.createCipher)(chachaCore, {
|
||||
counterRight: false,
|
||||
counterLength: 4,
|
||||
rounds: 8,
|
||||
});
|
||||
/**
|
||||
* Reduced 12-round chacha, described in original paper.
|
||||
*/
|
||||
exports.chacha12 = (0, _arx_js_1.createCipher)(chachaCore, {
|
||||
counterRight: false,
|
||||
counterLength: 4,
|
||||
rounds: 12,
|
||||
});
|
||||
const ZEROS16 = /* @__PURE__ */ new Uint8Array(16);
|
||||
// Pad to digest size with zeros
|
||||
const updatePadded = (h, msg) => {
|
||||
h.update(msg);
|
||||
const left = msg.length % 16;
|
||||
if (left)
|
||||
h.update(ZEROS16.subarray(left));
|
||||
};
|
||||
const ZEROS32 = /* @__PURE__ */ new Uint8Array(32);
|
||||
function computeTag(fn, key, nonce, data, AAD) {
|
||||
const authKey = fn(key, nonce, ZEROS32);
|
||||
const h = _poly1305_js_1.poly1305.create(authKey);
|
||||
if (AAD)
|
||||
updatePadded(h, AAD);
|
||||
updatePadded(h, data);
|
||||
const num = new Uint8Array(16);
|
||||
const view = (0, utils_js_1.createView)(num);
|
||||
(0, utils_js_1.setBigUint64)(view, 0, BigInt(AAD ? AAD.length : 0), true);
|
||||
(0, utils_js_1.setBigUint64)(view, 8, BigInt(data.length), true);
|
||||
h.update(num);
|
||||
const res = h.digest();
|
||||
authKey.fill(0);
|
||||
return res;
|
||||
}
|
||||
/**
|
||||
* AEAD algorithm from RFC 8439.
|
||||
* Salsa20 and chacha (RFC 8439) use poly1305 differently.
|
||||
* We could have composed them similar to:
|
||||
* https://github.com/paulmillr/scure-base/blob/b266c73dde977b1dd7ef40ef7a23cc15aab526b3/index.ts#L250
|
||||
* But it's hard because of authKey:
|
||||
* In salsa20, authKey changes position in salsa stream.
|
||||
* In chacha, authKey can't be computed inside computeTag, it modifies the counter.
|
||||
*/
|
||||
const _poly1305_aead = (xorStream) => (key, nonce, AAD) => {
|
||||
const tagLength = 16;
|
||||
(0, _assert_js_1.bytes)(key, 32);
|
||||
(0, _assert_js_1.bytes)(nonce);
|
||||
return {
|
||||
encrypt: (plaintext, output) => {
|
||||
const plength = plaintext.length;
|
||||
const clength = plength + tagLength;
|
||||
if (output) {
|
||||
(0, _assert_js_1.bytes)(output, clength);
|
||||
}
|
||||
else {
|
||||
output = new Uint8Array(clength);
|
||||
}
|
||||
xorStream(key, nonce, plaintext, output, 1);
|
||||
const tag = computeTag(xorStream, key, nonce, output.subarray(0, -tagLength), AAD);
|
||||
output.set(tag, plength); // append tag
|
||||
return output;
|
||||
},
|
||||
decrypt: (ciphertext, output) => {
|
||||
const clength = ciphertext.length;
|
||||
const plength = clength - tagLength;
|
||||
if (clength < tagLength)
|
||||
throw new Error(`encrypted data must be at least ${tagLength} bytes`);
|
||||
if (output) {
|
||||
(0, _assert_js_1.bytes)(output, plength);
|
||||
}
|
||||
else {
|
||||
output = new Uint8Array(plength);
|
||||
}
|
||||
const data = ciphertext.subarray(0, -tagLength);
|
||||
const passedTag = ciphertext.subarray(-tagLength);
|
||||
const tag = computeTag(xorStream, key, nonce, data, AAD);
|
||||
if (!(0, utils_js_1.equalBytes)(passedTag, tag))
|
||||
throw new Error('invalid tag');
|
||||
xorStream(key, nonce, data, output, 1);
|
||||
return output;
|
||||
},
|
||||
};
|
||||
};
|
||||
exports._poly1305_aead = _poly1305_aead;
|
||||
/**
|
||||
* ChaCha20-Poly1305 from RFC 8439.
|
||||
* With 12-byte nonce, it's not safe to use fill it with random (CSPRNG), due to collision chance.
|
||||
*/
|
||||
exports.chacha20poly1305 = (0, utils_js_1.wrapCipher)({ blockSize: 64, nonceLength: 12, tagLength: 16 }, (0, exports._poly1305_aead)(exports.chacha20));
|
||||
/**
|
||||
* XChaCha20-Poly1305 extended-nonce chacha.
|
||||
* https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-xchacha
|
||||
* With 24-byte nonce, it's safe to use fill it with random (CSPRNG).
|
||||
*/
|
||||
exports.xchacha20poly1305 = (0, utils_js_1.wrapCipher)({ blockSize: 64, nonceLength: 24, tagLength: 16 }, (0, exports._poly1305_aead)(exports.xchacha20));
|
||||
//# sourceMappingURL=chacha.js.map
|
||||
1
thrower_daemon/node_modules/@noble/ciphers/chacha.js.map
generated
vendored
Normal file
1
thrower_daemon/node_modules/@noble/ciphers/chacha.js.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
3
thrower_daemon/node_modules/@noble/ciphers/crypto.d.ts
generated
vendored
Normal file
3
thrower_daemon/node_modules/@noble/ciphers/crypto.d.ts
generated
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
export declare function randomBytes(bytesLength?: number): Uint8Array;
|
||||
export declare function getWebcryptoSubtle(): any;
|
||||
//# sourceMappingURL=crypto.d.ts.map
|
||||
1
thrower_daemon/node_modules/@noble/ciphers/crypto.d.ts.map
generated
vendored
Normal file
1
thrower_daemon/node_modules/@noble/ciphers/crypto.d.ts.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"crypto.d.ts","sourceRoot":"","sources":["src/crypto.ts"],"names":[],"mappings":"AAKA,wBAAgB,WAAW,CAAC,WAAW,SAAK,GAAG,UAAU,CAIxD;AAED,wBAAgB,kBAAkB,QAGjC"}
|
||||
17
thrower_daemon/node_modules/@noble/ciphers/crypto.js
generated
vendored
Normal file
17
thrower_daemon/node_modules/@noble/ciphers/crypto.js
generated
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.getWebcryptoSubtle = exports.randomBytes = void 0;
|
||||
const cr = typeof globalThis === 'object' && 'crypto' in globalThis ? globalThis.crypto : undefined;
|
||||
function randomBytes(bytesLength = 32) {
|
||||
if (cr && typeof cr.getRandomValues === 'function')
|
||||
return cr.getRandomValues(new Uint8Array(bytesLength));
|
||||
throw new Error('crypto.getRandomValues must be defined');
|
||||
}
|
||||
exports.randomBytes = randomBytes;
|
||||
function getWebcryptoSubtle() {
|
||||
if (cr && typeof cr.subtle === 'object' && cr.subtle != null)
|
||||
return cr.subtle;
|
||||
throw new Error('crypto.subtle must be defined');
|
||||
}
|
||||
exports.getWebcryptoSubtle = getWebcryptoSubtle;
|
||||
//# sourceMappingURL=crypto.js.map
|
||||
1
thrower_daemon/node_modules/@noble/ciphers/crypto.js.map
generated
vendored
Normal file
1
thrower_daemon/node_modules/@noble/ciphers/crypto.js.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"crypto.js","sourceRoot":"","sources":["src/crypto.ts"],"names":[],"mappings":";;;AAGA,MAAM,EAAE,GAAG,OAAO,UAAU,KAAK,QAAQ,IAAI,QAAQ,IAAI,UAAU,CAAC,CAAC,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC;AAEpG,SAAgB,WAAW,CAAC,WAAW,GAAG,EAAE;IAC1C,IAAI,EAAE,IAAI,OAAO,EAAE,CAAC,eAAe,KAAK,UAAU;QAChD,OAAO,EAAE,CAAC,eAAe,CAAC,IAAI,UAAU,CAAC,WAAW,CAAC,CAAC,CAAC;IACzD,MAAM,IAAI,KAAK,CAAC,wCAAwC,CAAC,CAAC;AAC5D,CAAC;AAJD,kCAIC;AAED,SAAgB,kBAAkB;IAChC,IAAI,EAAE,IAAI,OAAO,EAAE,CAAC,MAAM,KAAK,QAAQ,IAAI,EAAE,CAAC,MAAM,IAAI,IAAI;QAAE,OAAO,EAAE,CAAC,MAAM,CAAC;IAC/E,MAAM,IAAI,KAAK,CAAC,+BAA+B,CAAC,CAAC;AACnD,CAAC;AAHD,gDAGC"}
|
||||
3
thrower_daemon/node_modules/@noble/ciphers/cryptoNode.d.ts
generated
vendored
Normal file
3
thrower_daemon/node_modules/@noble/ciphers/cryptoNode.d.ts
generated
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
export declare function randomBytes(bytesLength?: number): Uint8Array;
|
||||
export declare function getWebcryptoSubtle(): any;
|
||||
//# sourceMappingURL=cryptoNode.d.ts.map
|
||||
1
thrower_daemon/node_modules/@noble/ciphers/cryptoNode.d.ts.map
generated
vendored
Normal file
1
thrower_daemon/node_modules/@noble/ciphers/cryptoNode.d.ts.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"cryptoNode.d.ts","sourceRoot":"","sources":["src/cryptoNode.ts"],"names":[],"mappings":"AAOA,wBAAgB,WAAW,CAAC,WAAW,SAAK,GAAG,UAAU,CAIxD;AAED,wBAAgB,kBAAkB,QAGjC"}
|
||||
22
thrower_daemon/node_modules/@noble/ciphers/cryptoNode.js
generated
vendored
Normal file
22
thrower_daemon/node_modules/@noble/ciphers/cryptoNode.js
generated
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.getWebcryptoSubtle = exports.randomBytes = void 0;
|
||||
// We use WebCrypto aka globalThis.crypto, which exists in browsers and node.js 16+.
|
||||
// See utils.ts for details.
|
||||
// The file will throw on node.js 14 and earlier.
|
||||
// @ts-ignore
|
||||
const nc = require("node:crypto");
|
||||
const cr = nc && typeof nc === 'object' && 'webcrypto' in nc ? nc.webcrypto : undefined;
|
||||
function randomBytes(bytesLength = 32) {
|
||||
if (cr && typeof cr.getRandomValues === 'function')
|
||||
return cr.getRandomValues(new Uint8Array(bytesLength));
|
||||
throw new Error('crypto.getRandomValues must be defined');
|
||||
}
|
||||
exports.randomBytes = randomBytes;
|
||||
function getWebcryptoSubtle() {
|
||||
if (cr && typeof cr.subtle === 'object' && cr.subtle != null)
|
||||
return cr.subtle;
|
||||
throw new Error('crypto.subtle must be defined');
|
||||
}
|
||||
exports.getWebcryptoSubtle = getWebcryptoSubtle;
|
||||
//# sourceMappingURL=cryptoNode.js.map
|
||||
1
thrower_daemon/node_modules/@noble/ciphers/cryptoNode.js.map
generated
vendored
Normal file
1
thrower_daemon/node_modules/@noble/ciphers/cryptoNode.js.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"cryptoNode.js","sourceRoot":"","sources":["src/cryptoNode.ts"],"names":[],"mappings":";;;AAAA,oFAAoF;AACpF,4BAA4B;AAC5B,iDAAiD;AACjD,aAAa;AACb,kCAAkC;AAClC,MAAM,EAAE,GAAG,EAAE,IAAI,OAAO,EAAE,KAAK,QAAQ,IAAI,WAAW,IAAI,EAAE,CAAC,CAAC,CAAE,EAAE,CAAC,SAAiB,CAAC,CAAC,CAAC,SAAS,CAAC;AAEjG,SAAgB,WAAW,CAAC,WAAW,GAAG,EAAE;IAC1C,IAAI,EAAE,IAAI,OAAO,EAAE,CAAC,eAAe,KAAK,UAAU;QAChD,OAAO,EAAE,CAAC,eAAe,CAAC,IAAI,UAAU,CAAC,WAAW,CAAC,CAAC,CAAC;IACzD,MAAM,IAAI,KAAK,CAAC,wCAAwC,CAAC,CAAC;AAC5D,CAAC;AAJD,kCAIC;AAED,SAAgB,kBAAkB;IAChC,IAAI,EAAE,IAAI,OAAO,EAAE,CAAC,MAAM,KAAK,QAAQ,IAAI,EAAE,CAAC,MAAM,IAAI,IAAI;QAAE,OAAO,EAAE,CAAC,MAAM,CAAC;IAC/E,MAAM,IAAI,KAAK,CAAC,+BAA+B,CAAC,CAAC;AACnD,CAAC;AAHD,gDAGC"}
|
||||
170
thrower_daemon/node_modules/@noble/ciphers/esm/_arx.js
generated
vendored
Normal file
170
thrower_daemon/node_modules/@noble/ciphers/esm/_arx.js
generated
vendored
Normal file
@@ -0,0 +1,170 @@
|
||||
// Basic utils for ARX (add-rotate-xor) salsa and chacha ciphers.
|
||||
import { number as anumber, bytes as abytes, bool as abool } from './_assert.js';
|
||||
import { checkOpts, u32 } from './utils.js';
|
||||
/*
|
||||
RFC8439 requires multi-step cipher stream, where
|
||||
authKey starts with counter: 0, actual msg with counter: 1.
|
||||
|
||||
For this, we need a way to re-use nonce / counter:
|
||||
|
||||
const counter = new Uint8Array(4);
|
||||
chacha(..., counter, ...); // counter is now 1
|
||||
chacha(..., counter, ...); // counter is now 2
|
||||
|
||||
This is complicated:
|
||||
|
||||
- 32-bit counters are enough, no need for 64-bit: max ArrayBuffer size in JS is 4GB
|
||||
- Original papers don't allow mutating counters
|
||||
- Counter overflow is undefined [^1]
|
||||
- Idea A: allow providing (nonce | counter) instead of just nonce, re-use it
|
||||
- Caveat: Cannot be re-used through all cases:
|
||||
- * chacha has (counter | nonce)
|
||||
- * xchacha has (nonce16 | counter | nonce16)
|
||||
- Idea B: separate nonce / counter and provide separate API for counter re-use
|
||||
- Caveat: there are different counter sizes depending on an algorithm.
|
||||
- salsa & chacha also differ in structures of key & sigma:
|
||||
salsa20: s[0] | k(4) | s[1] | nonce(2) | ctr(2) | s[2] | k(4) | s[3]
|
||||
chacha: s(4) | k(8) | ctr(1) | nonce(3)
|
||||
chacha20orig: s(4) | k(8) | ctr(2) | nonce(2)
|
||||
- Idea C: helper method such as `setSalsaState(key, nonce, sigma, data)`
|
||||
- Caveat: we can't re-use counter array
|
||||
|
||||
xchacha [^2] uses the subkey and remaining 8 byte nonce with ChaCha20 as normal
|
||||
(prefixed by 4 NUL bytes, since [RFC8439] specifies a 12-byte nonce).
|
||||
|
||||
[^1]: https://mailarchive.ietf.org/arch/msg/cfrg/gsOnTJzcbgG6OqD8Sc0GO5aR_tU/
|
||||
[^2]: https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-xchacha#appendix-A.2
|
||||
*/
|
||||
// We can't make top-level var depend on utils.utf8ToBytes
|
||||
// because it's not present in all envs. Creating a similar fn here
|
||||
const _utf8ToBytes = (str) => Uint8Array.from(str.split('').map((c) => c.charCodeAt(0)));
|
||||
const sigma16 = _utf8ToBytes('expand 16-byte k');
|
||||
const sigma32 = _utf8ToBytes('expand 32-byte k');
|
||||
const sigma16_32 = u32(sigma16);
|
||||
const sigma32_32 = u32(sigma32);
|
||||
export const sigma = sigma32_32.slice();
|
||||
export function rotl(a, b) {
|
||||
return (a << b) | (a >>> (32 - b));
|
||||
}
|
||||
// Is byte array aligned to 4 byte offset (u32)?
|
||||
function isAligned32(b) {
|
||||
return b.byteOffset % 4 === 0;
|
||||
}
|
||||
// Salsa and Chacha block length is always 512-bit
|
||||
const BLOCK_LEN = 64;
|
||||
const BLOCK_LEN32 = 16;
|
||||
// new Uint32Array([2**32]) // => Uint32Array(1) [ 0 ]
|
||||
// new Uint32Array([2**32-1]) // => Uint32Array(1) [ 4294967295 ]
|
||||
const MAX_COUNTER = 2 ** 32 - 1;
|
||||
const U32_EMPTY = new Uint32Array();
|
||||
function runCipher(core, sigma, key, nonce, data, output, counter, rounds) {
|
||||
const len = data.length;
|
||||
const block = new Uint8Array(BLOCK_LEN);
|
||||
const b32 = u32(block);
|
||||
// Make sure that buffers aligned to 4 bytes
|
||||
const isAligned = isAligned32(data) && isAligned32(output);
|
||||
const d32 = isAligned ? u32(data) : U32_EMPTY;
|
||||
const o32 = isAligned ? u32(output) : U32_EMPTY;
|
||||
for (let pos = 0; pos < len; counter++) {
|
||||
core(sigma, key, nonce, b32, counter, rounds);
|
||||
if (counter >= MAX_COUNTER)
|
||||
throw new Error('arx: counter overflow');
|
||||
const take = Math.min(BLOCK_LEN, len - pos);
|
||||
// aligned to 4 bytes
|
||||
if (isAligned && take === BLOCK_LEN) {
|
||||
const pos32 = pos / 4;
|
||||
if (pos % 4 !== 0)
|
||||
throw new Error('arx: invalid block position');
|
||||
for (let j = 0, posj; j < BLOCK_LEN32; j++) {
|
||||
posj = pos32 + j;
|
||||
o32[posj] = d32[posj] ^ b32[j];
|
||||
}
|
||||
pos += BLOCK_LEN;
|
||||
continue;
|
||||
}
|
||||
for (let j = 0, posj; j < take; j++) {
|
||||
posj = pos + j;
|
||||
output[posj] = data[posj] ^ block[j];
|
||||
}
|
||||
pos += take;
|
||||
}
|
||||
}
|
||||
export function createCipher(core, opts) {
|
||||
const { allowShortKeys, extendNonceFn, counterLength, counterRight, rounds } = checkOpts({ allowShortKeys: false, counterLength: 8, counterRight: false, rounds: 20 }, opts);
|
||||
if (typeof core !== 'function')
|
||||
throw new Error('core must be a function');
|
||||
anumber(counterLength);
|
||||
anumber(rounds);
|
||||
abool(counterRight);
|
||||
abool(allowShortKeys);
|
||||
return (key, nonce, data, output, counter = 0) => {
|
||||
abytes(key);
|
||||
abytes(nonce);
|
||||
abytes(data);
|
||||
const len = data.length;
|
||||
if (!output)
|
||||
output = new Uint8Array(len);
|
||||
abytes(output);
|
||||
anumber(counter);
|
||||
if (counter < 0 || counter >= MAX_COUNTER)
|
||||
throw new Error('arx: counter overflow');
|
||||
if (output.length < len)
|
||||
throw new Error(`arx: output (${output.length}) is shorter than data (${len})`);
|
||||
const toClean = [];
|
||||
// Key & sigma
|
||||
// key=16 -> sigma16, k=key|key
|
||||
// key=32 -> sigma32, k=key
|
||||
let l = key.length, k, sigma;
|
||||
if (l === 32) {
|
||||
k = key.slice();
|
||||
toClean.push(k);
|
||||
sigma = sigma32_32;
|
||||
}
|
||||
else if (l === 16 && allowShortKeys) {
|
||||
k = new Uint8Array(32);
|
||||
k.set(key);
|
||||
k.set(key, 16);
|
||||
sigma = sigma16_32;
|
||||
toClean.push(k);
|
||||
}
|
||||
else {
|
||||
throw new Error(`arx: invalid 32-byte key, got length=${l}`);
|
||||
}
|
||||
// Nonce
|
||||
// salsa20: 8 (8-byte counter)
|
||||
// chacha20orig: 8 (8-byte counter)
|
||||
// chacha20: 12 (4-byte counter)
|
||||
// xsalsa20: 24 (16 -> hsalsa, 8 -> old nonce)
|
||||
// xchacha20: 24 (16 -> hchacha, 8 -> old nonce)
|
||||
// Align nonce to 4 bytes
|
||||
if (!isAligned32(nonce)) {
|
||||
nonce = nonce.slice();
|
||||
toClean.push(nonce);
|
||||
}
|
||||
const k32 = u32(k);
|
||||
// hsalsa & hchacha: handle extended nonce
|
||||
if (extendNonceFn) {
|
||||
if (nonce.length !== 24)
|
||||
throw new Error(`arx: extended nonce must be 24 bytes`);
|
||||
extendNonceFn(sigma, k32, u32(nonce.subarray(0, 16)), k32);
|
||||
nonce = nonce.subarray(16);
|
||||
}
|
||||
// Handle nonce counter
|
||||
const nonceNcLen = 16 - counterLength;
|
||||
if (nonceNcLen !== nonce.length)
|
||||
throw new Error(`arx: nonce must be ${nonceNcLen} or 16 bytes`);
|
||||
// Pad counter when nonce is 64 bit
|
||||
if (nonceNcLen !== 12) {
|
||||
const nc = new Uint8Array(12);
|
||||
nc.set(nonce, counterRight ? 0 : 12 - nonce.length);
|
||||
nonce = nc;
|
||||
toClean.push(nonce);
|
||||
}
|
||||
const n32 = u32(nonce);
|
||||
runCipher(core, sigma, k32, n32, data, output, counter, rounds);
|
||||
while (toClean.length > 0)
|
||||
toClean.pop().fill(0);
|
||||
return output;
|
||||
};
|
||||
}
|
||||
//# sourceMappingURL=_arx.js.map
|
||||
1
thrower_daemon/node_modules/@noble/ciphers/esm/_arx.js.map
generated
vendored
Normal file
1
thrower_daemon/node_modules/@noble/ciphers/esm/_arx.js.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
41
thrower_daemon/node_modules/@noble/ciphers/esm/_assert.js
generated
vendored
Normal file
41
thrower_daemon/node_modules/@noble/ciphers/esm/_assert.js
generated
vendored
Normal file
@@ -0,0 +1,41 @@
|
||||
function number(n) {
|
||||
if (!Number.isSafeInteger(n) || n < 0)
|
||||
throw new Error(`positive integer expected, not ${n}`);
|
||||
}
|
||||
function bool(b) {
|
||||
if (typeof b !== 'boolean')
|
||||
throw new Error(`boolean expected, not ${b}`);
|
||||
}
|
||||
export function isBytes(a) {
|
||||
return (a instanceof Uint8Array ||
|
||||
(a != null && typeof a === 'object' && a.constructor.name === 'Uint8Array'));
|
||||
}
|
||||
function bytes(b, ...lengths) {
|
||||
if (!isBytes(b))
|
||||
throw new Error('Uint8Array expected');
|
||||
if (lengths.length > 0 && !lengths.includes(b.length))
|
||||
throw new Error(`Uint8Array expected of length ${lengths}, not of length=${b.length}`);
|
||||
}
|
||||
function hash(hash) {
|
||||
if (typeof hash !== 'function' || typeof hash.create !== 'function')
|
||||
throw new Error('hash must be wrapped by utils.wrapConstructor');
|
||||
number(hash.outputLen);
|
||||
number(hash.blockLen);
|
||||
}
|
||||
function exists(instance, checkFinished = true) {
|
||||
if (instance.destroyed)
|
||||
throw new Error('Hash instance has been destroyed');
|
||||
if (checkFinished && instance.finished)
|
||||
throw new Error('Hash#digest() has already been called');
|
||||
}
|
||||
function output(out, instance) {
|
||||
bytes(out);
|
||||
const min = instance.outputLen;
|
||||
if (out.length < min) {
|
||||
throw new Error(`digestInto() expects output buffer of length at least ${min}`);
|
||||
}
|
||||
}
|
||||
export { number, bool, bytes, hash, exists, output };
|
||||
const assert = { number, bool, bytes, hash, exists, output };
|
||||
export default assert;
|
||||
//# sourceMappingURL=_assert.js.map
|
||||
1
thrower_daemon/node_modules/@noble/ciphers/esm/_assert.js.map
generated
vendored
Normal file
1
thrower_daemon/node_modules/@noble/ciphers/esm/_assert.js.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"_assert.js","sourceRoot":"","sources":["../src/_assert.ts"],"names":[],"mappings":"AAAA,SAAS,MAAM,CAAC,CAAS;IACvB,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,kCAAkC,CAAC,EAAE,CAAC,CAAC;AAChG,CAAC;AAED,SAAS,IAAI,CAAC,CAAU;IACtB,IAAI,OAAO,CAAC,KAAK,SAAS;QAAE,MAAM,IAAI,KAAK,CAAC,yBAAyB,CAAC,EAAE,CAAC,CAAC;AAC5E,CAAC;AAED,MAAM,UAAU,OAAO,CAAC,CAAU;IAChC,OAAO,CACL,CAAC,YAAY,UAAU;QACvB,CAAC,CAAC,IAAI,IAAI,IAAI,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,CAAC,WAAW,CAAC,IAAI,KAAK,YAAY,CAAC,CAC5E,CAAC;AACJ,CAAC;AAED,SAAS,KAAK,CAAC,CAAyB,EAAE,GAAG,OAAiB;IAC5D,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,qBAAqB,CAAC,CAAC;IACxD,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC;QACnD,MAAM,IAAI,KAAK,CAAC,iCAAiC,OAAO,mBAAmB,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC;AAC3F,CAAC;AAQD,SAAS,IAAI,CAAC,IAAU;IACtB,IAAI,OAAO,IAAI,KAAK,UAAU,IAAI,OAAO,IAAI,CAAC,MAAM,KAAK,UAAU;QACjE,MAAM,IAAI,KAAK,CAAC,+CAA+C,CAAC,CAAC;IACnE,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IACvB,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;AACxB,CAAC;AAED,SAAS,MAAM,CAAC,QAAa,EAAE,aAAa,GAAG,IAAI;IACjD,IAAI,QAAQ,CAAC,SAAS;QAAE,MAAM,IAAI,KAAK,CAAC,kCAAkC,CAAC,CAAC;IAC5E,IAAI,aAAa,IAAI,QAAQ,CAAC,QAAQ;QAAE,MAAM,IAAI,KAAK,CAAC,uCAAuC,CAAC,CAAC;AACnG,CAAC;AAED,SAAS,MAAM,CAAC,GAAQ,EAAE,QAAa;IACrC,KAAK,CAAC,GAAG,CAAC,CAAC;IACX,MAAM,GAAG,GAAG,QAAQ,CAAC,SAAS,CAAC;IAC/B,IAAI,GAAG,CAAC,MAAM,GAAG,GAAG,EAAE,CAAC;QACrB,MAAM,IAAI,KAAK,CAAC,yDAAyD,GAAG,EAAE,CAAC,CAAC;IAClF,CAAC;AACH,CAAC;AAED,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC;AACrD,MAAM,MAAM,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC;AAC7D,eAAe,MAAM,CAAC"}
|
||||
287
thrower_daemon/node_modules/@noble/ciphers/esm/_micro.js
generated
vendored
Normal file
287
thrower_daemon/node_modules/@noble/ciphers/esm/_micro.js
generated
vendored
Normal file
@@ -0,0 +1,287 @@
|
||||
/*! noble-ciphers - MIT License (c) 2023 Paul Miller (paulmillr.com) */
|
||||
// prettier-ignore
|
||||
import { createView, setBigUint64, wrapCipher, bytesToHex, concatBytes, equalBytes, hexToNumber, numberToBytesBE, } from './utils.js';
|
||||
import { createCipher, rotl } from './_arx.js';
|
||||
import { bytes as abytes } from './_assert.js';
|
||||
/*
|
||||
noble-ciphers-micro: more auditable, but slower version of salsa20, chacha & poly1305.
|
||||
Implements the same algorithms that are present in other files, but without
|
||||
unrolled loops (https://en.wikipedia.org/wiki/Loop_unrolling).
|
||||
*/
|
||||
function bytesToNumberLE(bytes) {
|
||||
return hexToNumber(bytesToHex(Uint8Array.from(bytes).reverse()));
|
||||
}
|
||||
function numberToBytesLE(n, len) {
|
||||
return numberToBytesBE(n, len).reverse();
|
||||
}
|
||||
function salsaQR(x, a, b, c, d) {
|
||||
x[b] ^= rotl((x[a] + x[d]) | 0, 7);
|
||||
x[c] ^= rotl((x[b] + x[a]) | 0, 9);
|
||||
x[d] ^= rotl((x[c] + x[b]) | 0, 13);
|
||||
x[a] ^= rotl((x[d] + x[c]) | 0, 18);
|
||||
}
|
||||
// prettier-ignore
|
||||
function chachaQR(x, a, b, c, d) {
|
||||
x[a] = (x[a] + x[b]) | 0;
|
||||
x[d] = rotl(x[d] ^ x[a], 16);
|
||||
x[c] = (x[c] + x[d]) | 0;
|
||||
x[b] = rotl(x[b] ^ x[c], 12);
|
||||
x[a] = (x[a] + x[b]) | 0;
|
||||
x[d] = rotl(x[d] ^ x[a], 8);
|
||||
x[c] = (x[c] + x[d]) | 0;
|
||||
x[b] = rotl(x[b] ^ x[c], 7);
|
||||
}
|
||||
function salsaRound(x, rounds = 20) {
|
||||
for (let r = 0; r < rounds; r += 2) {
|
||||
salsaQR(x, 0, 4, 8, 12);
|
||||
salsaQR(x, 5, 9, 13, 1);
|
||||
salsaQR(x, 10, 14, 2, 6);
|
||||
salsaQR(x, 15, 3, 7, 11);
|
||||
salsaQR(x, 0, 1, 2, 3);
|
||||
salsaQR(x, 5, 6, 7, 4);
|
||||
salsaQR(x, 10, 11, 8, 9);
|
||||
salsaQR(x, 15, 12, 13, 14);
|
||||
}
|
||||
}
|
||||
function chachaRound(x, rounds = 20) {
|
||||
for (let r = 0; r < rounds; r += 2) {
|
||||
chachaQR(x, 0, 4, 8, 12);
|
||||
chachaQR(x, 1, 5, 9, 13);
|
||||
chachaQR(x, 2, 6, 10, 14);
|
||||
chachaQR(x, 3, 7, 11, 15);
|
||||
chachaQR(x, 0, 5, 10, 15);
|
||||
chachaQR(x, 1, 6, 11, 12);
|
||||
chachaQR(x, 2, 7, 8, 13);
|
||||
chachaQR(x, 3, 4, 9, 14);
|
||||
}
|
||||
}
|
||||
function salsaCore(s, k, n, out, cnt, rounds = 20) {
|
||||
// prettier-ignore
|
||||
const y = new Uint32Array([
|
||||
s[0], k[0], k[1], k[2], // "expa" Key Key Key
|
||||
k[3], s[1], n[0], n[1], // Key "nd 3" Nonce Nonce
|
||||
cnt, 0, s[2], k[4], // Pos. Pos. "2-by" Key
|
||||
k[5], k[6], k[7], s[3], // Key Key Key "te k"
|
||||
]);
|
||||
const x = y.slice();
|
||||
salsaRound(x, rounds);
|
||||
for (let i = 0; i < 16; i++)
|
||||
out[i] = (y[i] + x[i]) | 0;
|
||||
}
|
||||
// prettier-ignore
|
||||
export function hsalsa(s, k, i, o32) {
|
||||
const x = new Uint32Array([
|
||||
s[0], k[0], k[1], k[2],
|
||||
k[3], s[1], i[0], i[1],
|
||||
i[2], i[3], s[2], k[4],
|
||||
k[5], k[6], k[7], s[3]
|
||||
]);
|
||||
salsaRound(x, 20);
|
||||
let oi = 0;
|
||||
o32[oi++] = x[0];
|
||||
o32[oi++] = x[5];
|
||||
o32[oi++] = x[10];
|
||||
o32[oi++] = x[15];
|
||||
o32[oi++] = x[6];
|
||||
o32[oi++] = x[7];
|
||||
o32[oi++] = x[8];
|
||||
o32[oi++] = x[9];
|
||||
}
|
||||
function chachaCore(s, k, n, out, cnt, rounds = 20) {
|
||||
// prettier-ignore
|
||||
const y = new Uint32Array([
|
||||
s[0], s[1], s[2], s[3], // "expa" "nd 3" "2-by" "te k"
|
||||
k[0], k[1], k[2], k[3], // Key Key Key Key
|
||||
k[4], k[5], k[6], k[7], // Key Key Key Key
|
||||
cnt, n[0], n[1], n[2], // Counter Counter Nonce Nonce
|
||||
]);
|
||||
const x = y.slice();
|
||||
chachaRound(x, rounds);
|
||||
for (let i = 0; i < 16; i++)
|
||||
out[i] = (y[i] + x[i]) | 0;
|
||||
}
|
||||
// prettier-ignore
|
||||
export function hchacha(s, k, i, o32) {
|
||||
const x = new Uint32Array([
|
||||
s[0], s[1], s[2], s[3],
|
||||
k[0], k[1], k[2], k[3],
|
||||
k[4], k[5], k[6], k[7],
|
||||
i[0], i[1], i[2], i[3],
|
||||
]);
|
||||
chachaRound(x, 20);
|
||||
let oi = 0;
|
||||
o32[oi++] = x[0];
|
||||
o32[oi++] = x[1];
|
||||
o32[oi++] = x[2];
|
||||
o32[oi++] = x[3];
|
||||
o32[oi++] = x[12];
|
||||
o32[oi++] = x[13];
|
||||
o32[oi++] = x[14];
|
||||
o32[oi++] = x[15];
|
||||
}
|
||||
/**
|
||||
* salsa20, 12-byte nonce.
|
||||
*/
|
||||
export const salsa20 = /* @__PURE__ */ createCipher(salsaCore, {
|
||||
allowShortKeys: true,
|
||||
counterRight: true,
|
||||
});
|
||||
/**
|
||||
* xsalsa20, 24-byte nonce.
|
||||
*/
|
||||
export const xsalsa20 = /* @__PURE__ */ createCipher(salsaCore, {
|
||||
counterRight: true,
|
||||
extendNonceFn: hsalsa,
|
||||
});
|
||||
/**
|
||||
* chacha20 non-RFC, original version by djb. 8-byte nonce, 8-byte counter.
|
||||
*/
|
||||
export const chacha20orig = /* @__PURE__ */ createCipher(chachaCore, {
|
||||
allowShortKeys: true,
|
||||
counterRight: false,
|
||||
counterLength: 8,
|
||||
});
|
||||
/**
|
||||
* chacha20 RFC 8439 (IETF / TLS). 12-byte nonce, 4-byte counter.
|
||||
*/
|
||||
export const chacha20 = /* @__PURE__ */ createCipher(chachaCore, {
|
||||
counterRight: false,
|
||||
counterLength: 4,
|
||||
});
|
||||
/**
|
||||
* xchacha20 eXtended-nonce. https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-xchacha
|
||||
*/
|
||||
export const xchacha20 = /* @__PURE__ */ createCipher(chachaCore, {
|
||||
counterRight: false,
|
||||
counterLength: 8,
|
||||
extendNonceFn: hchacha,
|
||||
});
|
||||
/**
|
||||
* 8-round chacha from the original paper.
|
||||
*/
|
||||
export const chacha8 = /* @__PURE__ */ createCipher(chachaCore, {
|
||||
counterRight: false,
|
||||
counterLength: 4,
|
||||
rounds: 8,
|
||||
});
|
||||
/**
|
||||
* 12-round chacha from the original paper.
|
||||
*/
|
||||
export const chacha12 = /* @__PURE__ */ createCipher(chachaCore, {
|
||||
counterRight: false,
|
||||
counterLength: 4,
|
||||
rounds: 12,
|
||||
});
|
||||
const POW_2_130_5 = BigInt(2) ** BigInt(130) - BigInt(5);
|
||||
const POW_2_128_1 = BigInt(2) ** BigInt(16 * 8) - BigInt(1);
|
||||
const CLAMP_R = BigInt('0x0ffffffc0ffffffc0ffffffc0fffffff');
|
||||
const _0 = BigInt(0);
|
||||
const _1 = BigInt(1);
|
||||
// Can be speed-up using BigUint64Array, but would be more complicated
|
||||
export function poly1305(msg, key) {
|
||||
abytes(msg);
|
||||
abytes(key);
|
||||
let acc = _0;
|
||||
const r = bytesToNumberLE(key.subarray(0, 16)) & CLAMP_R;
|
||||
const s = bytesToNumberLE(key.subarray(16));
|
||||
// Process by 16 byte chunks
|
||||
for (let i = 0; i < msg.length; i += 16) {
|
||||
const m = msg.subarray(i, i + 16);
|
||||
const n = bytesToNumberLE(m) | (_1 << BigInt(8 * m.length));
|
||||
acc = ((acc + n) * r) % POW_2_130_5;
|
||||
}
|
||||
const res = (acc + s) & POW_2_128_1;
|
||||
return numberToBytesLE(res, 16);
|
||||
}
|
||||
function computeTag(fn, key, nonce, ciphertext, AAD) {
|
||||
const res = [];
|
||||
if (AAD) {
|
||||
res.push(AAD);
|
||||
const leftover = AAD.length % 16;
|
||||
if (leftover > 0)
|
||||
res.push(new Uint8Array(16 - leftover));
|
||||
}
|
||||
res.push(ciphertext);
|
||||
const leftover = ciphertext.length % 16;
|
||||
if (leftover > 0)
|
||||
res.push(new Uint8Array(16 - leftover));
|
||||
// Lengths
|
||||
const num = new Uint8Array(16);
|
||||
const view = createView(num);
|
||||
setBigUint64(view, 0, BigInt(AAD ? AAD.length : 0), true);
|
||||
setBigUint64(view, 8, BigInt(ciphertext.length), true);
|
||||
res.push(num);
|
||||
const authKey = fn(key, nonce, new Uint8Array(32));
|
||||
return poly1305(concatBytes(...res), authKey);
|
||||
}
|
||||
/**
|
||||
* xsalsa20-poly1305 eXtended-nonce (24 bytes) salsa.
|
||||
*/
|
||||
export const xsalsa20poly1305 = /* @__PURE__ */ wrapCipher({ blockSize: 64, nonceLength: 24, tagLength: 16 }, function xsalsa20poly1305(key, nonce) {
|
||||
abytes(key);
|
||||
abytes(nonce);
|
||||
return {
|
||||
encrypt: (plaintext) => {
|
||||
abytes(plaintext);
|
||||
const m = concatBytes(new Uint8Array(32), plaintext);
|
||||
const c = xsalsa20(key, nonce, m);
|
||||
const authKey = c.subarray(0, 32);
|
||||
const data = c.subarray(32);
|
||||
const tag = poly1305(data, authKey);
|
||||
return concatBytes(tag, data);
|
||||
},
|
||||
decrypt: (ciphertext) => {
|
||||
abytes(ciphertext);
|
||||
if (ciphertext.length < 16)
|
||||
throw new Error('encrypted data must be at least 16 bytes');
|
||||
const c = concatBytes(new Uint8Array(16), ciphertext);
|
||||
const authKey = xsalsa20(key, nonce, new Uint8Array(32));
|
||||
const tag = poly1305(c.subarray(32), authKey);
|
||||
if (!equalBytes(c.subarray(16, 32), tag))
|
||||
throw new Error('invalid poly1305 tag');
|
||||
return xsalsa20(key, nonce, c).subarray(32);
|
||||
},
|
||||
};
|
||||
});
|
||||
/**
|
||||
* Alias to xsalsa20-poly1305
|
||||
*/
|
||||
export function secretbox(key, nonce) {
|
||||
const xs = xsalsa20poly1305(key, nonce);
|
||||
return { seal: xs.encrypt, open: xs.decrypt };
|
||||
}
|
||||
export const _poly1305_aead = (fn) => (key, nonce, AAD) => {
|
||||
const tagLength = 16;
|
||||
const keyLength = 32;
|
||||
abytes(key, keyLength);
|
||||
abytes(nonce);
|
||||
return {
|
||||
encrypt: (plaintext) => {
|
||||
abytes(plaintext);
|
||||
const res = fn(key, nonce, plaintext, undefined, 1);
|
||||
const tag = computeTag(fn, key, nonce, res, AAD);
|
||||
return concatBytes(res, tag);
|
||||
},
|
||||
decrypt: (ciphertext) => {
|
||||
abytes(ciphertext);
|
||||
if (ciphertext.length < tagLength)
|
||||
throw new Error(`encrypted data must be at least ${tagLength} bytes`);
|
||||
const passedTag = ciphertext.subarray(-tagLength);
|
||||
const data = ciphertext.subarray(0, -tagLength);
|
||||
const tag = computeTag(fn, key, nonce, data, AAD);
|
||||
if (!equalBytes(passedTag, tag))
|
||||
throw new Error('invalid poly1305 tag');
|
||||
return fn(key, nonce, data, undefined, 1);
|
||||
},
|
||||
};
|
||||
};
|
||||
/**
|
||||
* chacha20-poly1305 12-byte-nonce chacha.
|
||||
*/
|
||||
export const chacha20poly1305 = /* @__PURE__ */ wrapCipher({ blockSize: 64, nonceLength: 12, tagLength: 16 }, _poly1305_aead(chacha20));
|
||||
/**
|
||||
* xchacha20-poly1305 eXtended-nonce (24 bytes) chacha.
|
||||
* With 24-byte nonce, it's safe to use fill it with random (CSPRNG).
|
||||
*/
|
||||
export const xchacha20poly1305 = /* @__PURE__ */ wrapCipher({ blockSize: 64, nonceLength: 24, tagLength: 16 }, _poly1305_aead(xchacha20));
|
||||
//# sourceMappingURL=_micro.js.map
|
||||
1
thrower_daemon/node_modules/@noble/ciphers/esm/_micro.js.map
generated
vendored
Normal file
1
thrower_daemon/node_modules/@noble/ciphers/esm/_micro.js.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
264
thrower_daemon/node_modules/@noble/ciphers/esm/_poly1305.js
generated
vendored
Normal file
264
thrower_daemon/node_modules/@noble/ciphers/esm/_poly1305.js
generated
vendored
Normal file
@@ -0,0 +1,264 @@
|
||||
import { exists as aexists, bytes as abytes, output as aoutput } from './_assert.js';
|
||||
import { toBytes } from './utils.js';
|
||||
// Poly1305 is a fast and parallel secret-key message-authentication code.
|
||||
// https://cr.yp.to/mac.html, https://cr.yp.to/mac/poly1305-20050329.pdf
|
||||
// https://datatracker.ietf.org/doc/html/rfc8439
|
||||
// Based on Public Domain poly1305-donna https://github.com/floodyberry/poly1305-donna
|
||||
const u8to16 = (a, i) => (a[i++] & 0xff) | ((a[i++] & 0xff) << 8);
|
||||
class Poly1305 {
|
||||
constructor(key) {
|
||||
this.blockLen = 16;
|
||||
this.outputLen = 16;
|
||||
this.buffer = new Uint8Array(16);
|
||||
this.r = new Uint16Array(10);
|
||||
this.h = new Uint16Array(10);
|
||||
this.pad = new Uint16Array(8);
|
||||
this.pos = 0;
|
||||
this.finished = false;
|
||||
key = toBytes(key);
|
||||
abytes(key, 32);
|
||||
const t0 = u8to16(key, 0);
|
||||
const t1 = u8to16(key, 2);
|
||||
const t2 = u8to16(key, 4);
|
||||
const t3 = u8to16(key, 6);
|
||||
const t4 = u8to16(key, 8);
|
||||
const t5 = u8to16(key, 10);
|
||||
const t6 = u8to16(key, 12);
|
||||
const t7 = u8to16(key, 14);
|
||||
// https://github.com/floodyberry/poly1305-donna/blob/e6ad6e091d30d7f4ec2d4f978be1fcfcbce72781/poly1305-donna-16.h#L47
|
||||
this.r[0] = t0 & 0x1fff;
|
||||
this.r[1] = ((t0 >>> 13) | (t1 << 3)) & 0x1fff;
|
||||
this.r[2] = ((t1 >>> 10) | (t2 << 6)) & 0x1f03;
|
||||
this.r[3] = ((t2 >>> 7) | (t3 << 9)) & 0x1fff;
|
||||
this.r[4] = ((t3 >>> 4) | (t4 << 12)) & 0x00ff;
|
||||
this.r[5] = (t4 >>> 1) & 0x1ffe;
|
||||
this.r[6] = ((t4 >>> 14) | (t5 << 2)) & 0x1fff;
|
||||
this.r[7] = ((t5 >>> 11) | (t6 << 5)) & 0x1f81;
|
||||
this.r[8] = ((t6 >>> 8) | (t7 << 8)) & 0x1fff;
|
||||
this.r[9] = (t7 >>> 5) & 0x007f;
|
||||
for (let i = 0; i < 8; i++)
|
||||
this.pad[i] = u8to16(key, 16 + 2 * i);
|
||||
}
|
||||
process(data, offset, isLast = false) {
|
||||
const hibit = isLast ? 0 : 1 << 11;
|
||||
const { h, r } = this;
|
||||
const r0 = r[0];
|
||||
const r1 = r[1];
|
||||
const r2 = r[2];
|
||||
const r3 = r[3];
|
||||
const r4 = r[4];
|
||||
const r5 = r[5];
|
||||
const r6 = r[6];
|
||||
const r7 = r[7];
|
||||
const r8 = r[8];
|
||||
const r9 = r[9];
|
||||
const t0 = u8to16(data, offset + 0);
|
||||
const t1 = u8to16(data, offset + 2);
|
||||
const t2 = u8to16(data, offset + 4);
|
||||
const t3 = u8to16(data, offset + 6);
|
||||
const t4 = u8to16(data, offset + 8);
|
||||
const t5 = u8to16(data, offset + 10);
|
||||
const t6 = u8to16(data, offset + 12);
|
||||
const t7 = u8to16(data, offset + 14);
|
||||
let h0 = h[0] + (t0 & 0x1fff);
|
||||
let h1 = h[1] + (((t0 >>> 13) | (t1 << 3)) & 0x1fff);
|
||||
let h2 = h[2] + (((t1 >>> 10) | (t2 << 6)) & 0x1fff);
|
||||
let h3 = h[3] + (((t2 >>> 7) | (t3 << 9)) & 0x1fff);
|
||||
let h4 = h[4] + (((t3 >>> 4) | (t4 << 12)) & 0x1fff);
|
||||
let h5 = h[5] + ((t4 >>> 1) & 0x1fff);
|
||||
let h6 = h[6] + (((t4 >>> 14) | (t5 << 2)) & 0x1fff);
|
||||
let h7 = h[7] + (((t5 >>> 11) | (t6 << 5)) & 0x1fff);
|
||||
let h8 = h[8] + (((t6 >>> 8) | (t7 << 8)) & 0x1fff);
|
||||
let h9 = h[9] + ((t7 >>> 5) | hibit);
|
||||
let c = 0;
|
||||
let d0 = c + h0 * r0 + h1 * (5 * r9) + h2 * (5 * r8) + h3 * (5 * r7) + h4 * (5 * r6);
|
||||
c = d0 >>> 13;
|
||||
d0 &= 0x1fff;
|
||||
d0 += h5 * (5 * r5) + h6 * (5 * r4) + h7 * (5 * r3) + h8 * (5 * r2) + h9 * (5 * r1);
|
||||
c += d0 >>> 13;
|
||||
d0 &= 0x1fff;
|
||||
let d1 = c + h0 * r1 + h1 * r0 + h2 * (5 * r9) + h3 * (5 * r8) + h4 * (5 * r7);
|
||||
c = d1 >>> 13;
|
||||
d1 &= 0x1fff;
|
||||
d1 += h5 * (5 * r6) + h6 * (5 * r5) + h7 * (5 * r4) + h8 * (5 * r3) + h9 * (5 * r2);
|
||||
c += d1 >>> 13;
|
||||
d1 &= 0x1fff;
|
||||
let d2 = c + h0 * r2 + h1 * r1 + h2 * r0 + h3 * (5 * r9) + h4 * (5 * r8);
|
||||
c = d2 >>> 13;
|
||||
d2 &= 0x1fff;
|
||||
d2 += h5 * (5 * r7) + h6 * (5 * r6) + h7 * (5 * r5) + h8 * (5 * r4) + h9 * (5 * r3);
|
||||
c += d2 >>> 13;
|
||||
d2 &= 0x1fff;
|
||||
let d3 = c + h0 * r3 + h1 * r2 + h2 * r1 + h3 * r0 + h4 * (5 * r9);
|
||||
c = d3 >>> 13;
|
||||
d3 &= 0x1fff;
|
||||
d3 += h5 * (5 * r8) + h6 * (5 * r7) + h7 * (5 * r6) + h8 * (5 * r5) + h9 * (5 * r4);
|
||||
c += d3 >>> 13;
|
||||
d3 &= 0x1fff;
|
||||
let d4 = c + h0 * r4 + h1 * r3 + h2 * r2 + h3 * r1 + h4 * r0;
|
||||
c = d4 >>> 13;
|
||||
d4 &= 0x1fff;
|
||||
d4 += h5 * (5 * r9) + h6 * (5 * r8) + h7 * (5 * r7) + h8 * (5 * r6) + h9 * (5 * r5);
|
||||
c += d4 >>> 13;
|
||||
d4 &= 0x1fff;
|
||||
let d5 = c + h0 * r5 + h1 * r4 + h2 * r3 + h3 * r2 + h4 * r1;
|
||||
c = d5 >>> 13;
|
||||
d5 &= 0x1fff;
|
||||
d5 += h5 * r0 + h6 * (5 * r9) + h7 * (5 * r8) + h8 * (5 * r7) + h9 * (5 * r6);
|
||||
c += d5 >>> 13;
|
||||
d5 &= 0x1fff;
|
||||
let d6 = c + h0 * r6 + h1 * r5 + h2 * r4 + h3 * r3 + h4 * r2;
|
||||
c = d6 >>> 13;
|
||||
d6 &= 0x1fff;
|
||||
d6 += h5 * r1 + h6 * r0 + h7 * (5 * r9) + h8 * (5 * r8) + h9 * (5 * r7);
|
||||
c += d6 >>> 13;
|
||||
d6 &= 0x1fff;
|
||||
let d7 = c + h0 * r7 + h1 * r6 + h2 * r5 + h3 * r4 + h4 * r3;
|
||||
c = d7 >>> 13;
|
||||
d7 &= 0x1fff;
|
||||
d7 += h5 * r2 + h6 * r1 + h7 * r0 + h8 * (5 * r9) + h9 * (5 * r8);
|
||||
c += d7 >>> 13;
|
||||
d7 &= 0x1fff;
|
||||
let d8 = c + h0 * r8 + h1 * r7 + h2 * r6 + h3 * r5 + h4 * r4;
|
||||
c = d8 >>> 13;
|
||||
d8 &= 0x1fff;
|
||||
d8 += h5 * r3 + h6 * r2 + h7 * r1 + h8 * r0 + h9 * (5 * r9);
|
||||
c += d8 >>> 13;
|
||||
d8 &= 0x1fff;
|
||||
let d9 = c + h0 * r9 + h1 * r8 + h2 * r7 + h3 * r6 + h4 * r5;
|
||||
c = d9 >>> 13;
|
||||
d9 &= 0x1fff;
|
||||
d9 += h5 * r4 + h6 * r3 + h7 * r2 + h8 * r1 + h9 * r0;
|
||||
c += d9 >>> 13;
|
||||
d9 &= 0x1fff;
|
||||
c = ((c << 2) + c) | 0;
|
||||
c = (c + d0) | 0;
|
||||
d0 = c & 0x1fff;
|
||||
c = c >>> 13;
|
||||
d1 += c;
|
||||
h[0] = d0;
|
||||
h[1] = d1;
|
||||
h[2] = d2;
|
||||
h[3] = d3;
|
||||
h[4] = d4;
|
||||
h[5] = d5;
|
||||
h[6] = d6;
|
||||
h[7] = d7;
|
||||
h[8] = d8;
|
||||
h[9] = d9;
|
||||
}
|
||||
finalize() {
|
||||
const { h, pad } = this;
|
||||
const g = new Uint16Array(10);
|
||||
let c = h[1] >>> 13;
|
||||
h[1] &= 0x1fff;
|
||||
for (let i = 2; i < 10; i++) {
|
||||
h[i] += c;
|
||||
c = h[i] >>> 13;
|
||||
h[i] &= 0x1fff;
|
||||
}
|
||||
h[0] += c * 5;
|
||||
c = h[0] >>> 13;
|
||||
h[0] &= 0x1fff;
|
||||
h[1] += c;
|
||||
c = h[1] >>> 13;
|
||||
h[1] &= 0x1fff;
|
||||
h[2] += c;
|
||||
g[0] = h[0] + 5;
|
||||
c = g[0] >>> 13;
|
||||
g[0] &= 0x1fff;
|
||||
for (let i = 1; i < 10; i++) {
|
||||
g[i] = h[i] + c;
|
||||
c = g[i] >>> 13;
|
||||
g[i] &= 0x1fff;
|
||||
}
|
||||
g[9] -= 1 << 13;
|
||||
let mask = (c ^ 1) - 1;
|
||||
for (let i = 0; i < 10; i++)
|
||||
g[i] &= mask;
|
||||
mask = ~mask;
|
||||
for (let i = 0; i < 10; i++)
|
||||
h[i] = (h[i] & mask) | g[i];
|
||||
h[0] = (h[0] | (h[1] << 13)) & 0xffff;
|
||||
h[1] = ((h[1] >>> 3) | (h[2] << 10)) & 0xffff;
|
||||
h[2] = ((h[2] >>> 6) | (h[3] << 7)) & 0xffff;
|
||||
h[3] = ((h[3] >>> 9) | (h[4] << 4)) & 0xffff;
|
||||
h[4] = ((h[4] >>> 12) | (h[5] << 1) | (h[6] << 14)) & 0xffff;
|
||||
h[5] = ((h[6] >>> 2) | (h[7] << 11)) & 0xffff;
|
||||
h[6] = ((h[7] >>> 5) | (h[8] << 8)) & 0xffff;
|
||||
h[7] = ((h[8] >>> 8) | (h[9] << 5)) & 0xffff;
|
||||
let f = h[0] + pad[0];
|
||||
h[0] = f & 0xffff;
|
||||
for (let i = 1; i < 8; i++) {
|
||||
f = (((h[i] + pad[i]) | 0) + (f >>> 16)) | 0;
|
||||
h[i] = f & 0xffff;
|
||||
}
|
||||
}
|
||||
update(data) {
|
||||
aexists(this);
|
||||
const { buffer, blockLen } = this;
|
||||
data = toBytes(data);
|
||||
const len = data.length;
|
||||
for (let pos = 0; pos < len;) {
|
||||
const take = Math.min(blockLen - this.pos, len - pos);
|
||||
// Fast path: we have at least one block in input
|
||||
if (take === blockLen) {
|
||||
for (; blockLen <= len - pos; pos += blockLen)
|
||||
this.process(data, pos);
|
||||
continue;
|
||||
}
|
||||
buffer.set(data.subarray(pos, pos + take), this.pos);
|
||||
this.pos += take;
|
||||
pos += take;
|
||||
if (this.pos === blockLen) {
|
||||
this.process(buffer, 0, false);
|
||||
this.pos = 0;
|
||||
}
|
||||
}
|
||||
return this;
|
||||
}
|
||||
destroy() {
|
||||
this.h.fill(0);
|
||||
this.r.fill(0);
|
||||
this.buffer.fill(0);
|
||||
this.pad.fill(0);
|
||||
}
|
||||
digestInto(out) {
|
||||
aexists(this);
|
||||
aoutput(out, this);
|
||||
this.finished = true;
|
||||
const { buffer, h } = this;
|
||||
let { pos } = this;
|
||||
if (pos) {
|
||||
buffer[pos++] = 1;
|
||||
// buffer.subarray(pos).fill(0);
|
||||
for (; pos < 16; pos++)
|
||||
buffer[pos] = 0;
|
||||
this.process(buffer, 0, true);
|
||||
}
|
||||
this.finalize();
|
||||
let opos = 0;
|
||||
for (let i = 0; i < 8; i++) {
|
||||
out[opos++] = h[i] >>> 0;
|
||||
out[opos++] = h[i] >>> 8;
|
||||
}
|
||||
return out;
|
||||
}
|
||||
digest() {
|
||||
const { buffer, outputLen } = this;
|
||||
this.digestInto(buffer);
|
||||
const res = buffer.slice(0, outputLen);
|
||||
this.destroy();
|
||||
return res;
|
||||
}
|
||||
}
|
||||
export function wrapConstructorWithKey(hashCons) {
|
||||
const hashC = (msg, key) => hashCons(key).update(toBytes(msg)).digest();
|
||||
const tmp = hashCons(new Uint8Array(32));
|
||||
hashC.outputLen = tmp.outputLen;
|
||||
hashC.blockLen = tmp.blockLen;
|
||||
hashC.create = (key) => hashCons(key);
|
||||
return hashC;
|
||||
}
|
||||
export const poly1305 = wrapConstructorWithKey((key) => new Poly1305(key));
|
||||
//# sourceMappingURL=_poly1305.js.map
|
||||
1
thrower_daemon/node_modules/@noble/ciphers/esm/_poly1305.js.map
generated
vendored
Normal file
1
thrower_daemon/node_modules/@noble/ciphers/esm/_poly1305.js.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
217
thrower_daemon/node_modules/@noble/ciphers/esm/_polyval.js
generated
vendored
Normal file
217
thrower_daemon/node_modules/@noble/ciphers/esm/_polyval.js
generated
vendored
Normal file
@@ -0,0 +1,217 @@
|
||||
import { createView, toBytes, u32 } from './utils.js';
|
||||
import { bytes as abytes, exists as aexists, output as aoutput } from './_assert.js';
|
||||
// GHash from AES-GCM and its little-endian "mirror image" Polyval from AES-SIV.
|
||||
// Implemented in terms of GHash with conversion function for keys
|
||||
// GCM GHASH from NIST SP800-38d, SIV from RFC 8452.
|
||||
// https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-38d.pdf
|
||||
// GHASH modulo: x^128 + x^7 + x^2 + x + 1
|
||||
// POLYVAL modulo: x^128 + x^127 + x^126 + x^121 + 1
|
||||
const BLOCK_SIZE = 16;
|
||||
// TODO: rewrite
|
||||
// temporary padding buffer
|
||||
const ZEROS16 = /* @__PURE__ */ new Uint8Array(16);
|
||||
const ZEROS32 = u32(ZEROS16);
|
||||
const POLY = 0xe1; // v = 2*v % POLY
|
||||
// v = 2*v % POLY
|
||||
// NOTE: because x + x = 0 (add/sub is same), mul2(x) != x+x
|
||||
// We can multiply any number using montgomery ladder and this function (works as double, add is simple xor)
|
||||
const mul2 = (s0, s1, s2, s3) => {
|
||||
const hiBit = s3 & 1;
|
||||
return {
|
||||
s3: (s2 << 31) | (s3 >>> 1),
|
||||
s2: (s1 << 31) | (s2 >>> 1),
|
||||
s1: (s0 << 31) | (s1 >>> 1),
|
||||
s0: (s0 >>> 1) ^ ((POLY << 24) & -(hiBit & 1)), // reduce % poly
|
||||
};
|
||||
};
|
||||
const swapLE = (n) => (((n >>> 0) & 0xff) << 24) |
|
||||
(((n >>> 8) & 0xff) << 16) |
|
||||
(((n >>> 16) & 0xff) << 8) |
|
||||
((n >>> 24) & 0xff) |
|
||||
0;
|
||||
/**
|
||||
* `mulX_POLYVAL(ByteReverse(H))` from spec
|
||||
* @param k mutated in place
|
||||
*/
|
||||
export function _toGHASHKey(k) {
|
||||
k.reverse();
|
||||
const hiBit = k[15] & 1;
|
||||
// k >>= 1
|
||||
let carry = 0;
|
||||
for (let i = 0; i < k.length; i++) {
|
||||
const t = k[i];
|
||||
k[i] = (t >>> 1) | carry;
|
||||
carry = (t & 1) << 7;
|
||||
}
|
||||
k[0] ^= -hiBit & 0xe1; // if (hiBit) n ^= 0xe1000000000000000000000000000000;
|
||||
return k;
|
||||
}
|
||||
const estimateWindow = (bytes) => {
|
||||
if (bytes > 64 * 1024)
|
||||
return 8;
|
||||
if (bytes > 1024)
|
||||
return 4;
|
||||
return 2;
|
||||
};
|
||||
class GHASH {
|
||||
// We select bits per window adaptively based on expectedLength
|
||||
constructor(key, expectedLength) {
|
||||
this.blockLen = BLOCK_SIZE;
|
||||
this.outputLen = BLOCK_SIZE;
|
||||
this.s0 = 0;
|
||||
this.s1 = 0;
|
||||
this.s2 = 0;
|
||||
this.s3 = 0;
|
||||
this.finished = false;
|
||||
key = toBytes(key);
|
||||
abytes(key, 16);
|
||||
const kView = createView(key);
|
||||
let k0 = kView.getUint32(0, false);
|
||||
let k1 = kView.getUint32(4, false);
|
||||
let k2 = kView.getUint32(8, false);
|
||||
let k3 = kView.getUint32(12, false);
|
||||
// generate table of doubled keys (half of montgomery ladder)
|
||||
const doubles = [];
|
||||
for (let i = 0; i < 128; i++) {
|
||||
doubles.push({ s0: swapLE(k0), s1: swapLE(k1), s2: swapLE(k2), s3: swapLE(k3) });
|
||||
({ s0: k0, s1: k1, s2: k2, s3: k3 } = mul2(k0, k1, k2, k3));
|
||||
}
|
||||
const W = estimateWindow(expectedLength || 1024);
|
||||
if (![1, 2, 4, 8].includes(W))
|
||||
throw new Error(`ghash: wrong window size=${W}, should be 2, 4 or 8`);
|
||||
this.W = W;
|
||||
const bits = 128; // always 128 bits;
|
||||
const windows = bits / W;
|
||||
const windowSize = (this.windowSize = 2 ** W);
|
||||
const items = [];
|
||||
// Create precompute table for window of W bits
|
||||
for (let w = 0; w < windows; w++) {
|
||||
// truth table: 00, 01, 10, 11
|
||||
for (let byte = 0; byte < windowSize; byte++) {
|
||||
// prettier-ignore
|
||||
let s0 = 0, s1 = 0, s2 = 0, s3 = 0;
|
||||
for (let j = 0; j < W; j++) {
|
||||
const bit = (byte >>> (W - j - 1)) & 1;
|
||||
if (!bit)
|
||||
continue;
|
||||
const { s0: d0, s1: d1, s2: d2, s3: d3 } = doubles[W * w + j];
|
||||
(s0 ^= d0), (s1 ^= d1), (s2 ^= d2), (s3 ^= d3);
|
||||
}
|
||||
items.push({ s0, s1, s2, s3 });
|
||||
}
|
||||
}
|
||||
this.t = items;
|
||||
}
|
||||
_updateBlock(s0, s1, s2, s3) {
|
||||
(s0 ^= this.s0), (s1 ^= this.s1), (s2 ^= this.s2), (s3 ^= this.s3);
|
||||
const { W, t, windowSize } = this;
|
||||
// prettier-ignore
|
||||
let o0 = 0, o1 = 0, o2 = 0, o3 = 0;
|
||||
const mask = (1 << W) - 1; // 2**W will kill performance.
|
||||
let w = 0;
|
||||
for (const num of [s0, s1, s2, s3]) {
|
||||
for (let bytePos = 0; bytePos < 4; bytePos++) {
|
||||
const byte = (num >>> (8 * bytePos)) & 0xff;
|
||||
for (let bitPos = 8 / W - 1; bitPos >= 0; bitPos--) {
|
||||
const bit = (byte >>> (W * bitPos)) & mask;
|
||||
const { s0: e0, s1: e1, s2: e2, s3: e3 } = t[w * windowSize + bit];
|
||||
(o0 ^= e0), (o1 ^= e1), (o2 ^= e2), (o3 ^= e3);
|
||||
w += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
this.s0 = o0;
|
||||
this.s1 = o1;
|
||||
this.s2 = o2;
|
||||
this.s3 = o3;
|
||||
}
|
||||
update(data) {
|
||||
data = toBytes(data);
|
||||
aexists(this);
|
||||
const b32 = u32(data);
|
||||
const blocks = Math.floor(data.length / BLOCK_SIZE);
|
||||
const left = data.length % BLOCK_SIZE;
|
||||
for (let i = 0; i < blocks; i++) {
|
||||
this._updateBlock(b32[i * 4 + 0], b32[i * 4 + 1], b32[i * 4 + 2], b32[i * 4 + 3]);
|
||||
}
|
||||
if (left) {
|
||||
ZEROS16.set(data.subarray(blocks * BLOCK_SIZE));
|
||||
this._updateBlock(ZEROS32[0], ZEROS32[1], ZEROS32[2], ZEROS32[3]);
|
||||
ZEROS32.fill(0); // clean tmp buffer
|
||||
}
|
||||
return this;
|
||||
}
|
||||
destroy() {
|
||||
const { t } = this;
|
||||
// clean precompute table
|
||||
for (const elm of t) {
|
||||
(elm.s0 = 0), (elm.s1 = 0), (elm.s2 = 0), (elm.s3 = 0);
|
||||
}
|
||||
}
|
||||
digestInto(out) {
|
||||
aexists(this);
|
||||
aoutput(out, this);
|
||||
this.finished = true;
|
||||
const { s0, s1, s2, s3 } = this;
|
||||
const o32 = u32(out);
|
||||
o32[0] = s0;
|
||||
o32[1] = s1;
|
||||
o32[2] = s2;
|
||||
o32[3] = s3;
|
||||
return out;
|
||||
}
|
||||
digest() {
|
||||
const res = new Uint8Array(BLOCK_SIZE);
|
||||
this.digestInto(res);
|
||||
this.destroy();
|
||||
return res;
|
||||
}
|
||||
}
|
||||
class Polyval extends GHASH {
|
||||
constructor(key, expectedLength) {
|
||||
key = toBytes(key);
|
||||
const ghKey = _toGHASHKey(key.slice());
|
||||
super(ghKey, expectedLength);
|
||||
ghKey.fill(0);
|
||||
}
|
||||
update(data) {
|
||||
data = toBytes(data);
|
||||
aexists(this);
|
||||
const b32 = u32(data);
|
||||
const left = data.length % BLOCK_SIZE;
|
||||
const blocks = Math.floor(data.length / BLOCK_SIZE);
|
||||
for (let i = 0; i < blocks; i++) {
|
||||
this._updateBlock(swapLE(b32[i * 4 + 3]), swapLE(b32[i * 4 + 2]), swapLE(b32[i * 4 + 1]), swapLE(b32[i * 4 + 0]));
|
||||
}
|
||||
if (left) {
|
||||
ZEROS16.set(data.subarray(blocks * BLOCK_SIZE));
|
||||
this._updateBlock(swapLE(ZEROS32[3]), swapLE(ZEROS32[2]), swapLE(ZEROS32[1]), swapLE(ZEROS32[0]));
|
||||
ZEROS32.fill(0); // clean tmp buffer
|
||||
}
|
||||
return this;
|
||||
}
|
||||
digestInto(out) {
|
||||
aexists(this);
|
||||
aoutput(out, this);
|
||||
this.finished = true;
|
||||
// tmp ugly hack
|
||||
const { s0, s1, s2, s3 } = this;
|
||||
const o32 = u32(out);
|
||||
o32[0] = s0;
|
||||
o32[1] = s1;
|
||||
o32[2] = s2;
|
||||
o32[3] = s3;
|
||||
return out.reverse();
|
||||
}
|
||||
}
|
||||
function wrapConstructorWithKey(hashCons) {
|
||||
const hashC = (msg, key) => hashCons(key, msg.length).update(toBytes(msg)).digest();
|
||||
const tmp = hashCons(new Uint8Array(16), 0);
|
||||
hashC.outputLen = tmp.outputLen;
|
||||
hashC.blockLen = tmp.blockLen;
|
||||
hashC.create = (key, expectedLength) => hashCons(key, expectedLength);
|
||||
return hashC;
|
||||
}
|
||||
export const ghash = wrapConstructorWithKey((key, expectedLength) => new GHASH(key, expectedLength));
|
||||
export const polyval = wrapConstructorWithKey((key, expectedLength) => new Polyval(key, expectedLength));
|
||||
//# sourceMappingURL=_polyval.js.map
|
||||
1
thrower_daemon/node_modules/@noble/ciphers/esm/_polyval.js.map
generated
vendored
Normal file
1
thrower_daemon/node_modules/@noble/ciphers/esm/_polyval.js.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
670
thrower_daemon/node_modules/@noble/ciphers/esm/aes.js
generated
vendored
Normal file
670
thrower_daemon/node_modules/@noble/ciphers/esm/aes.js
generated
vendored
Normal file
@@ -0,0 +1,670 @@
|
||||
// prettier-ignore
|
||||
import { wrapCipher, createView, setBigUint64, equalBytes, u32, u8, } from './utils.js';
|
||||
import { ghash, polyval } from './_polyval.js';
|
||||
import { bytes as abytes } from './_assert.js';
|
||||
/*
|
||||
AES (Advanced Encryption Standard) aka Rijndael block cipher.
|
||||
|
||||
Data is split into 128-bit blocks. Encrypted in 10/12/14 rounds (128/192/256 bits). In every round:
|
||||
1. **S-box**, table substitution
|
||||
2. **Shift rows**, cyclic shift left of all rows of data array
|
||||
3. **Mix columns**, multiplying every column by fixed polynomial
|
||||
4. **Add round key**, round_key xor i-th column of array
|
||||
|
||||
Resources:
|
||||
- FIPS-197 https://csrc.nist.gov/files/pubs/fips/197/final/docs/fips-197.pdf
|
||||
- Original proposal: https://csrc.nist.gov/csrc/media/projects/cryptographic-standards-and-guidelines/documents/aes-development/rijndael-ammended.pdf
|
||||
*/
|
||||
const BLOCK_SIZE = 16;
|
||||
const BLOCK_SIZE32 = 4;
|
||||
const EMPTY_BLOCK = new Uint8Array(BLOCK_SIZE);
|
||||
const POLY = 0x11b; // 1 + x + x**3 + x**4 + x**8
|
||||
// TODO: remove multiplication, binary ops only
|
||||
function mul2(n) {
|
||||
return (n << 1) ^ (POLY & -(n >> 7));
|
||||
}
|
||||
function mul(a, b) {
|
||||
let res = 0;
|
||||
for (; b > 0; b >>= 1) {
|
||||
// Montgomery ladder
|
||||
res ^= a & -(b & 1); // if (b&1) res ^=a (but const-time).
|
||||
a = mul2(a); // a = 2*a
|
||||
}
|
||||
return res;
|
||||
}
|
||||
// AES S-box is generated using finite field inversion,
|
||||
// an affine transform, and xor of a constant 0x63.
|
||||
const sbox = /* @__PURE__ */ (() => {
|
||||
let t = new Uint8Array(256);
|
||||
for (let i = 0, x = 1; i < 256; i++, x ^= mul2(x))
|
||||
t[i] = x;
|
||||
const box = new Uint8Array(256);
|
||||
box[0] = 0x63; // first elm
|
||||
for (let i = 0; i < 255; i++) {
|
||||
let x = t[255 - i];
|
||||
x |= x << 8;
|
||||
box[t[i]] = (x ^ (x >> 4) ^ (x >> 5) ^ (x >> 6) ^ (x >> 7) ^ 0x63) & 0xff;
|
||||
}
|
||||
return box;
|
||||
})();
|
||||
// Inverted S-box
|
||||
const invSbox = /* @__PURE__ */ sbox.map((_, j) => sbox.indexOf(j));
|
||||
// Rotate u32 by 8
|
||||
const rotr32_8 = (n) => (n << 24) | (n >>> 8);
|
||||
const rotl32_8 = (n) => (n << 8) | (n >>> 24);
|
||||
// T-table is optimization suggested in 5.2 of original proposal (missed from FIPS-197). Changes:
|
||||
// - LE instead of BE
|
||||
// - bigger tables: T0 and T1 are merged into T01 table and T2 & T3 into T23;
|
||||
// so index is u16, instead of u8. This speeds up things, unexpectedly
|
||||
function genTtable(sbox, fn) {
|
||||
if (sbox.length !== 256)
|
||||
throw new Error('Wrong sbox length');
|
||||
const T0 = new Uint32Array(256).map((_, j) => fn(sbox[j]));
|
||||
const T1 = T0.map(rotl32_8);
|
||||
const T2 = T1.map(rotl32_8);
|
||||
const T3 = T2.map(rotl32_8);
|
||||
const T01 = new Uint32Array(256 * 256);
|
||||
const T23 = new Uint32Array(256 * 256);
|
||||
const sbox2 = new Uint16Array(256 * 256);
|
||||
for (let i = 0; i < 256; i++) {
|
||||
for (let j = 0; j < 256; j++) {
|
||||
const idx = i * 256 + j;
|
||||
T01[idx] = T0[i] ^ T1[j];
|
||||
T23[idx] = T2[i] ^ T3[j];
|
||||
sbox2[idx] = (sbox[i] << 8) | sbox[j];
|
||||
}
|
||||
}
|
||||
return { sbox, sbox2, T0, T1, T2, T3, T01, T23 };
|
||||
}
|
||||
const tableEncoding = /* @__PURE__ */ genTtable(sbox, (s) => (mul(s, 3) << 24) | (s << 16) | (s << 8) | mul(s, 2));
|
||||
const tableDecoding = /* @__PURE__ */ genTtable(invSbox, (s) => (mul(s, 11) << 24) | (mul(s, 13) << 16) | (mul(s, 9) << 8) | mul(s, 14));
|
||||
const xPowers = /* @__PURE__ */ (() => {
|
||||
const p = new Uint8Array(16);
|
||||
for (let i = 0, x = 1; i < 16; i++, x = mul2(x))
|
||||
p[i] = x;
|
||||
return p;
|
||||
})();
|
||||
export function expandKeyLE(key) {
|
||||
abytes(key);
|
||||
const len = key.length;
|
||||
if (![16, 24, 32].includes(len))
|
||||
throw new Error(`aes: wrong key size: should be 16, 24 or 32, got: ${len}`);
|
||||
const { sbox2 } = tableEncoding;
|
||||
const k32 = u32(key);
|
||||
const Nk = k32.length;
|
||||
const subByte = (n) => applySbox(sbox2, n, n, n, n);
|
||||
const xk = new Uint32Array(len + 28); // expanded key
|
||||
xk.set(k32);
|
||||
// 4.3.1 Key expansion
|
||||
for (let i = Nk; i < xk.length; i++) {
|
||||
let t = xk[i - 1];
|
||||
if (i % Nk === 0)
|
||||
t = subByte(rotr32_8(t)) ^ xPowers[i / Nk - 1];
|
||||
else if (Nk > 6 && i % Nk === 4)
|
||||
t = subByte(t);
|
||||
xk[i] = xk[i - Nk] ^ t;
|
||||
}
|
||||
return xk;
|
||||
}
|
||||
export function expandKeyDecLE(key) {
|
||||
const encKey = expandKeyLE(key);
|
||||
const xk = encKey.slice();
|
||||
const Nk = encKey.length;
|
||||
const { sbox2 } = tableEncoding;
|
||||
const { T0, T1, T2, T3 } = tableDecoding;
|
||||
// Inverse key by chunks of 4 (rounds)
|
||||
for (let i = 0; i < Nk; i += 4) {
|
||||
for (let j = 0; j < 4; j++)
|
||||
xk[i + j] = encKey[Nk - i - 4 + j];
|
||||
}
|
||||
encKey.fill(0);
|
||||
// apply InvMixColumn except first & last round
|
||||
for (let i = 4; i < Nk - 4; i++) {
|
||||
const x = xk[i];
|
||||
const w = applySbox(sbox2, x, x, x, x);
|
||||
xk[i] = T0[w & 0xff] ^ T1[(w >>> 8) & 0xff] ^ T2[(w >>> 16) & 0xff] ^ T3[w >>> 24];
|
||||
}
|
||||
return xk;
|
||||
}
|
||||
// Apply tables
|
||||
function apply0123(T01, T23, s0, s1, s2, s3) {
|
||||
return (T01[((s0 << 8) & 0xff00) | ((s1 >>> 8) & 0xff)] ^
|
||||
T23[((s2 >>> 8) & 0xff00) | ((s3 >>> 24) & 0xff)]);
|
||||
}
|
||||
function applySbox(sbox2, s0, s1, s2, s3) {
|
||||
return (sbox2[(s0 & 0xff) | (s1 & 0xff00)] |
|
||||
(sbox2[((s2 >>> 16) & 0xff) | ((s3 >>> 16) & 0xff00)] << 16));
|
||||
}
|
||||
function encrypt(xk, s0, s1, s2, s3) {
|
||||
const { sbox2, T01, T23 } = tableEncoding;
|
||||
let k = 0;
|
||||
(s0 ^= xk[k++]), (s1 ^= xk[k++]), (s2 ^= xk[k++]), (s3 ^= xk[k++]);
|
||||
const rounds = xk.length / 4 - 2;
|
||||
for (let i = 0; i < rounds; i++) {
|
||||
const t0 = xk[k++] ^ apply0123(T01, T23, s0, s1, s2, s3);
|
||||
const t1 = xk[k++] ^ apply0123(T01, T23, s1, s2, s3, s0);
|
||||
const t2 = xk[k++] ^ apply0123(T01, T23, s2, s3, s0, s1);
|
||||
const t3 = xk[k++] ^ apply0123(T01, T23, s3, s0, s1, s2);
|
||||
(s0 = t0), (s1 = t1), (s2 = t2), (s3 = t3);
|
||||
}
|
||||
// last round (without mixcolumns, so using SBOX2 table)
|
||||
const t0 = xk[k++] ^ applySbox(sbox2, s0, s1, s2, s3);
|
||||
const t1 = xk[k++] ^ applySbox(sbox2, s1, s2, s3, s0);
|
||||
const t2 = xk[k++] ^ applySbox(sbox2, s2, s3, s0, s1);
|
||||
const t3 = xk[k++] ^ applySbox(sbox2, s3, s0, s1, s2);
|
||||
return { s0: t0, s1: t1, s2: t2, s3: t3 };
|
||||
}
|
||||
function decrypt(xk, s0, s1, s2, s3) {
|
||||
const { sbox2, T01, T23 } = tableDecoding;
|
||||
let k = 0;
|
||||
(s0 ^= xk[k++]), (s1 ^= xk[k++]), (s2 ^= xk[k++]), (s3 ^= xk[k++]);
|
||||
const rounds = xk.length / 4 - 2;
|
||||
for (let i = 0; i < rounds; i++) {
|
||||
const t0 = xk[k++] ^ apply0123(T01, T23, s0, s3, s2, s1);
|
||||
const t1 = xk[k++] ^ apply0123(T01, T23, s1, s0, s3, s2);
|
||||
const t2 = xk[k++] ^ apply0123(T01, T23, s2, s1, s0, s3);
|
||||
const t3 = xk[k++] ^ apply0123(T01, T23, s3, s2, s1, s0);
|
||||
(s0 = t0), (s1 = t1), (s2 = t2), (s3 = t3);
|
||||
}
|
||||
// Last round
|
||||
const t0 = xk[k++] ^ applySbox(sbox2, s0, s3, s2, s1);
|
||||
const t1 = xk[k++] ^ applySbox(sbox2, s1, s0, s3, s2);
|
||||
const t2 = xk[k++] ^ applySbox(sbox2, s2, s1, s0, s3);
|
||||
const t3 = xk[k++] ^ applySbox(sbox2, s3, s2, s1, s0);
|
||||
return { s0: t0, s1: t1, s2: t2, s3: t3 };
|
||||
}
|
||||
function getDst(len, dst) {
|
||||
if (!dst)
|
||||
return new Uint8Array(len);
|
||||
abytes(dst);
|
||||
if (dst.length < len)
|
||||
throw new Error(`aes: wrong destination length, expected at least ${len}, got: ${dst.length}`);
|
||||
return dst;
|
||||
}
|
||||
// TODO: investigate merging with ctr32
|
||||
function ctrCounter(xk, nonce, src, dst) {
|
||||
abytes(nonce, BLOCK_SIZE);
|
||||
abytes(src);
|
||||
const srcLen = src.length;
|
||||
dst = getDst(srcLen, dst);
|
||||
const ctr = nonce;
|
||||
const c32 = u32(ctr);
|
||||
// Fill block (empty, ctr=0)
|
||||
let { s0, s1, s2, s3 } = encrypt(xk, c32[0], c32[1], c32[2], c32[3]);
|
||||
const src32 = u32(src);
|
||||
const dst32 = u32(dst);
|
||||
// process blocks
|
||||
for (let i = 0; i + 4 <= src32.length; i += 4) {
|
||||
dst32[i + 0] = src32[i + 0] ^ s0;
|
||||
dst32[i + 1] = src32[i + 1] ^ s1;
|
||||
dst32[i + 2] = src32[i + 2] ^ s2;
|
||||
dst32[i + 3] = src32[i + 3] ^ s3;
|
||||
// Full 128 bit counter with wrap around
|
||||
let carry = 1;
|
||||
for (let i = ctr.length - 1; i >= 0; i--) {
|
||||
carry = (carry + (ctr[i] & 0xff)) | 0;
|
||||
ctr[i] = carry & 0xff;
|
||||
carry >>>= 8;
|
||||
}
|
||||
({ s0, s1, s2, s3 } = encrypt(xk, c32[0], c32[1], c32[2], c32[3]));
|
||||
}
|
||||
// leftovers (less than block)
|
||||
// It's possible to handle > u32 fast, but is it worth it?
|
||||
const start = BLOCK_SIZE * Math.floor(src32.length / BLOCK_SIZE32);
|
||||
if (start < srcLen) {
|
||||
const b32 = new Uint32Array([s0, s1, s2, s3]);
|
||||
const buf = u8(b32);
|
||||
for (let i = start, pos = 0; i < srcLen; i++, pos++)
|
||||
dst[i] = src[i] ^ buf[pos];
|
||||
}
|
||||
return dst;
|
||||
}
|
||||
// AES CTR with overflowing 32 bit counter
|
||||
// It's possible to do 32le significantly simpler (and probably faster) by using u32.
|
||||
// But, we need both, and perf bottleneck is in ghash anyway.
|
||||
function ctr32(xk, isLE, nonce, src, dst) {
|
||||
abytes(nonce, BLOCK_SIZE);
|
||||
abytes(src);
|
||||
dst = getDst(src.length, dst);
|
||||
const ctr = nonce; // write new value to nonce, so it can be re-used
|
||||
const c32 = u32(ctr);
|
||||
const view = createView(ctr);
|
||||
const src32 = u32(src);
|
||||
const dst32 = u32(dst);
|
||||
const ctrPos = isLE ? 0 : 12;
|
||||
const srcLen = src.length;
|
||||
// Fill block (empty, ctr=0)
|
||||
let ctrNum = view.getUint32(ctrPos, isLE); // read current counter value
|
||||
let { s0, s1, s2, s3 } = encrypt(xk, c32[0], c32[1], c32[2], c32[3]);
|
||||
// process blocks
|
||||
for (let i = 0; i + 4 <= src32.length; i += 4) {
|
||||
dst32[i + 0] = src32[i + 0] ^ s0;
|
||||
dst32[i + 1] = src32[i + 1] ^ s1;
|
||||
dst32[i + 2] = src32[i + 2] ^ s2;
|
||||
dst32[i + 3] = src32[i + 3] ^ s3;
|
||||
ctrNum = (ctrNum + 1) >>> 0; // u32 wrap
|
||||
view.setUint32(ctrPos, ctrNum, isLE);
|
||||
({ s0, s1, s2, s3 } = encrypt(xk, c32[0], c32[1], c32[2], c32[3]));
|
||||
}
|
||||
// leftovers (less than a block)
|
||||
const start = BLOCK_SIZE * Math.floor(src32.length / BLOCK_SIZE32);
|
||||
if (start < srcLen) {
|
||||
const b32 = new Uint32Array([s0, s1, s2, s3]);
|
||||
const buf = u8(b32);
|
||||
for (let i = start, pos = 0; i < srcLen; i++, pos++)
|
||||
dst[i] = src[i] ^ buf[pos];
|
||||
}
|
||||
return dst;
|
||||
}
|
||||
/**
|
||||
* CTR: counter mode. Creates stream cipher.
|
||||
* Requires good IV. Parallelizable. OK, but no MAC.
|
||||
*/
|
||||
export const ctr = wrapCipher({ blockSize: 16, nonceLength: 16 }, function ctr(key, nonce) {
|
||||
abytes(key);
|
||||
abytes(nonce, BLOCK_SIZE);
|
||||
function processCtr(buf, dst) {
|
||||
const xk = expandKeyLE(key);
|
||||
const n = nonce.slice();
|
||||
const out = ctrCounter(xk, n, buf, dst);
|
||||
xk.fill(0);
|
||||
n.fill(0);
|
||||
return out;
|
||||
}
|
||||
return {
|
||||
encrypt: (plaintext, dst) => processCtr(plaintext, dst),
|
||||
decrypt: (ciphertext, dst) => processCtr(ciphertext, dst),
|
||||
};
|
||||
});
|
||||
function validateBlockDecrypt(data) {
|
||||
abytes(data);
|
||||
if (data.length % BLOCK_SIZE !== 0) {
|
||||
throw new Error(`aes/(cbc-ecb).decrypt ciphertext should consist of blocks with size ${BLOCK_SIZE}`);
|
||||
}
|
||||
}
|
||||
function validateBlockEncrypt(plaintext, pcks5, dst) {
|
||||
let outLen = plaintext.length;
|
||||
const remaining = outLen % BLOCK_SIZE;
|
||||
if (!pcks5 && remaining !== 0)
|
||||
throw new Error('aec/(cbc-ecb): unpadded plaintext with disabled padding');
|
||||
const b = u32(plaintext);
|
||||
if (pcks5) {
|
||||
let left = BLOCK_SIZE - remaining;
|
||||
if (!left)
|
||||
left = BLOCK_SIZE; // if no bytes left, create empty padding block
|
||||
outLen = outLen + left;
|
||||
}
|
||||
const out = getDst(outLen, dst);
|
||||
const o = u32(out);
|
||||
return { b, o, out };
|
||||
}
|
||||
function validatePCKS(data, pcks5) {
|
||||
if (!pcks5)
|
||||
return data;
|
||||
const len = data.length;
|
||||
if (!len)
|
||||
throw new Error(`aes/pcks5: empty ciphertext not allowed`);
|
||||
const lastByte = data[len - 1];
|
||||
if (lastByte <= 0 || lastByte > 16)
|
||||
throw new Error(`aes/pcks5: wrong padding byte: ${lastByte}`);
|
||||
const out = data.subarray(0, -lastByte);
|
||||
for (let i = 0; i < lastByte; i++)
|
||||
if (data[len - i - 1] !== lastByte)
|
||||
throw new Error(`aes/pcks5: wrong padding`);
|
||||
return out;
|
||||
}
|
||||
function padPCKS(left) {
|
||||
const tmp = new Uint8Array(16);
|
||||
const tmp32 = u32(tmp);
|
||||
tmp.set(left);
|
||||
const paddingByte = BLOCK_SIZE - left.length;
|
||||
for (let i = BLOCK_SIZE - paddingByte; i < BLOCK_SIZE; i++)
|
||||
tmp[i] = paddingByte;
|
||||
return tmp32;
|
||||
}
|
||||
/**
|
||||
* ECB: Electronic CodeBook. Simple deterministic replacement.
|
||||
* Dangerous: always map x to y. See [AES Penguin](https://words.filippo.io/the-ecb-penguin/).
|
||||
*/
|
||||
export const ecb = wrapCipher({ blockSize: 16 }, function ecb(key, opts = {}) {
|
||||
abytes(key);
|
||||
const pcks5 = !opts.disablePadding;
|
||||
return {
|
||||
encrypt: (plaintext, dst) => {
|
||||
abytes(plaintext);
|
||||
const { b, o, out: _out } = validateBlockEncrypt(plaintext, pcks5, dst);
|
||||
const xk = expandKeyLE(key);
|
||||
let i = 0;
|
||||
for (; i + 4 <= b.length;) {
|
||||
const { s0, s1, s2, s3 } = encrypt(xk, b[i + 0], b[i + 1], b[i + 2], b[i + 3]);
|
||||
(o[i++] = s0), (o[i++] = s1), (o[i++] = s2), (o[i++] = s3);
|
||||
}
|
||||
if (pcks5) {
|
||||
const tmp32 = padPCKS(plaintext.subarray(i * 4));
|
||||
const { s0, s1, s2, s3 } = encrypt(xk, tmp32[0], tmp32[1], tmp32[2], tmp32[3]);
|
||||
(o[i++] = s0), (o[i++] = s1), (o[i++] = s2), (o[i++] = s3);
|
||||
}
|
||||
xk.fill(0);
|
||||
return _out;
|
||||
},
|
||||
decrypt: (ciphertext, dst) => {
|
||||
validateBlockDecrypt(ciphertext);
|
||||
const xk = expandKeyDecLE(key);
|
||||
const out = getDst(ciphertext.length, dst);
|
||||
const b = u32(ciphertext);
|
||||
const o = u32(out);
|
||||
for (let i = 0; i + 4 <= b.length;) {
|
||||
const { s0, s1, s2, s3 } = decrypt(xk, b[i + 0], b[i + 1], b[i + 2], b[i + 3]);
|
||||
(o[i++] = s0), (o[i++] = s1), (o[i++] = s2), (o[i++] = s3);
|
||||
}
|
||||
xk.fill(0);
|
||||
return validatePCKS(out, pcks5);
|
||||
},
|
||||
};
|
||||
});
|
||||
/**
|
||||
* CBC: Cipher-Block-Chaining. Key is previous round’s block.
|
||||
* Fragile: needs proper padding. Unauthenticated: needs MAC.
|
||||
*/
|
||||
export const cbc = wrapCipher({ blockSize: 16, nonceLength: 16 }, function cbc(key, iv, opts = {}) {
|
||||
abytes(key);
|
||||
abytes(iv, 16);
|
||||
const pcks5 = !opts.disablePadding;
|
||||
return {
|
||||
encrypt: (plaintext, dst) => {
|
||||
const xk = expandKeyLE(key);
|
||||
const { b, o, out: _out } = validateBlockEncrypt(plaintext, pcks5, dst);
|
||||
const n32 = u32(iv);
|
||||
// prettier-ignore
|
||||
let s0 = n32[0], s1 = n32[1], s2 = n32[2], s3 = n32[3];
|
||||
let i = 0;
|
||||
for (; i + 4 <= b.length;) {
|
||||
(s0 ^= b[i + 0]), (s1 ^= b[i + 1]), (s2 ^= b[i + 2]), (s3 ^= b[i + 3]);
|
||||
({ s0, s1, s2, s3 } = encrypt(xk, s0, s1, s2, s3));
|
||||
(o[i++] = s0), (o[i++] = s1), (o[i++] = s2), (o[i++] = s3);
|
||||
}
|
||||
if (pcks5) {
|
||||
const tmp32 = padPCKS(plaintext.subarray(i * 4));
|
||||
(s0 ^= tmp32[0]), (s1 ^= tmp32[1]), (s2 ^= tmp32[2]), (s3 ^= tmp32[3]);
|
||||
({ s0, s1, s2, s3 } = encrypt(xk, s0, s1, s2, s3));
|
||||
(o[i++] = s0), (o[i++] = s1), (o[i++] = s2), (o[i++] = s3);
|
||||
}
|
||||
xk.fill(0);
|
||||
return _out;
|
||||
},
|
||||
decrypt: (ciphertext, dst) => {
|
||||
validateBlockDecrypt(ciphertext);
|
||||
const xk = expandKeyDecLE(key);
|
||||
const n32 = u32(iv);
|
||||
const out = getDst(ciphertext.length, dst);
|
||||
const b = u32(ciphertext);
|
||||
const o = u32(out);
|
||||
// prettier-ignore
|
||||
let s0 = n32[0], s1 = n32[1], s2 = n32[2], s3 = n32[3];
|
||||
for (let i = 0; i + 4 <= b.length;) {
|
||||
// prettier-ignore
|
||||
const ps0 = s0, ps1 = s1, ps2 = s2, ps3 = s3;
|
||||
(s0 = b[i + 0]), (s1 = b[i + 1]), (s2 = b[i + 2]), (s3 = b[i + 3]);
|
||||
const { s0: o0, s1: o1, s2: o2, s3: o3 } = decrypt(xk, s0, s1, s2, s3);
|
||||
(o[i++] = o0 ^ ps0), (o[i++] = o1 ^ ps1), (o[i++] = o2 ^ ps2), (o[i++] = o3 ^ ps3);
|
||||
}
|
||||
xk.fill(0);
|
||||
return validatePCKS(out, pcks5);
|
||||
},
|
||||
};
|
||||
});
|
||||
/**
|
||||
* CFB: Cipher Feedback Mode. The input for the block cipher is the previous cipher output.
|
||||
* Unauthenticated: needs MAC.
|
||||
*/
|
||||
export const cfb = wrapCipher({ blockSize: 16, nonceLength: 16 }, function cfb(key, iv) {
|
||||
abytes(key);
|
||||
abytes(iv, 16);
|
||||
function processCfb(src, isEncrypt, dst) {
|
||||
const xk = expandKeyLE(key);
|
||||
const srcLen = src.length;
|
||||
dst = getDst(srcLen, dst);
|
||||
const src32 = u32(src);
|
||||
const dst32 = u32(dst);
|
||||
const next32 = isEncrypt ? dst32 : src32;
|
||||
const n32 = u32(iv);
|
||||
// prettier-ignore
|
||||
let s0 = n32[0], s1 = n32[1], s2 = n32[2], s3 = n32[3];
|
||||
for (let i = 0; i + 4 <= src32.length;) {
|
||||
const { s0: e0, s1: e1, s2: e2, s3: e3 } = encrypt(xk, s0, s1, s2, s3);
|
||||
dst32[i + 0] = src32[i + 0] ^ e0;
|
||||
dst32[i + 1] = src32[i + 1] ^ e1;
|
||||
dst32[i + 2] = src32[i + 2] ^ e2;
|
||||
dst32[i + 3] = src32[i + 3] ^ e3;
|
||||
(s0 = next32[i++]), (s1 = next32[i++]), (s2 = next32[i++]), (s3 = next32[i++]);
|
||||
}
|
||||
// leftovers (less than block)
|
||||
const start = BLOCK_SIZE * Math.floor(src32.length / BLOCK_SIZE32);
|
||||
if (start < srcLen) {
|
||||
({ s0, s1, s2, s3 } = encrypt(xk, s0, s1, s2, s3));
|
||||
const buf = u8(new Uint32Array([s0, s1, s2, s3]));
|
||||
for (let i = start, pos = 0; i < srcLen; i++, pos++)
|
||||
dst[i] = src[i] ^ buf[pos];
|
||||
buf.fill(0);
|
||||
}
|
||||
xk.fill(0);
|
||||
return dst;
|
||||
}
|
||||
return {
|
||||
encrypt: (plaintext, dst) => processCfb(plaintext, true, dst),
|
||||
decrypt: (ciphertext, dst) => processCfb(ciphertext, false, dst),
|
||||
};
|
||||
});
|
||||
// TODO: merge with chacha, however gcm has bitLen while chacha has byteLen
|
||||
function computeTag(fn, isLE, key, data, AAD) {
|
||||
const h = fn.create(key, data.length + (AAD?.length || 0));
|
||||
if (AAD)
|
||||
h.update(AAD);
|
||||
h.update(data);
|
||||
const num = new Uint8Array(16);
|
||||
const view = createView(num);
|
||||
if (AAD)
|
||||
setBigUint64(view, 0, BigInt(AAD.length * 8), isLE);
|
||||
setBigUint64(view, 8, BigInt(data.length * 8), isLE);
|
||||
h.update(num);
|
||||
return h.digest();
|
||||
}
|
||||
/**
|
||||
* GCM: Galois/Counter Mode.
|
||||
* Good, modern version of CTR, parallel, with MAC.
|
||||
* Be careful: MACs can be forged.
|
||||
*/
|
||||
export const gcm = wrapCipher({ blockSize: 16, nonceLength: 12, tagLength: 16 }, function gcm(key, nonce, AAD) {
|
||||
abytes(nonce);
|
||||
// Nonce can be pretty much anything (even 1 byte). But smaller nonces less secure.
|
||||
if (nonce.length === 0)
|
||||
throw new Error('aes/gcm: empty nonce');
|
||||
const tagLength = 16;
|
||||
function _computeTag(authKey, tagMask, data) {
|
||||
const tag = computeTag(ghash, false, authKey, data, AAD);
|
||||
for (let i = 0; i < tagMask.length; i++)
|
||||
tag[i] ^= tagMask[i];
|
||||
return tag;
|
||||
}
|
||||
function deriveKeys() {
|
||||
const xk = expandKeyLE(key);
|
||||
const authKey = EMPTY_BLOCK.slice();
|
||||
const counter = EMPTY_BLOCK.slice();
|
||||
ctr32(xk, false, counter, counter, authKey);
|
||||
if (nonce.length === 12) {
|
||||
counter.set(nonce);
|
||||
}
|
||||
else {
|
||||
// Spec (NIST 800-38d) supports variable size nonce.
|
||||
// Not supported for now, but can be useful.
|
||||
const nonceLen = EMPTY_BLOCK.slice();
|
||||
const view = createView(nonceLen);
|
||||
setBigUint64(view, 8, BigInt(nonce.length * 8), false);
|
||||
// ghash(nonce || u64be(0) || u64be(nonceLen*8))
|
||||
ghash.create(authKey).update(nonce).update(nonceLen).digestInto(counter);
|
||||
}
|
||||
const tagMask = ctr32(xk, false, counter, EMPTY_BLOCK);
|
||||
return { xk, authKey, counter, tagMask };
|
||||
}
|
||||
return {
|
||||
encrypt: (plaintext) => {
|
||||
abytes(plaintext);
|
||||
const { xk, authKey, counter, tagMask } = deriveKeys();
|
||||
const out = new Uint8Array(plaintext.length + tagLength);
|
||||
ctr32(xk, false, counter, plaintext, out);
|
||||
const tag = _computeTag(authKey, tagMask, out.subarray(0, out.length - tagLength));
|
||||
out.set(tag, plaintext.length);
|
||||
xk.fill(0);
|
||||
return out;
|
||||
},
|
||||
decrypt: (ciphertext) => {
|
||||
abytes(ciphertext);
|
||||
if (ciphertext.length < tagLength)
|
||||
throw new Error(`aes/gcm: ciphertext less than tagLen (${tagLength})`);
|
||||
const { xk, authKey, counter, tagMask } = deriveKeys();
|
||||
const data = ciphertext.subarray(0, -tagLength);
|
||||
const passedTag = ciphertext.subarray(-tagLength);
|
||||
const tag = _computeTag(authKey, tagMask, data);
|
||||
if (!equalBytes(tag, passedTag))
|
||||
throw new Error('aes/gcm: invalid ghash tag');
|
||||
const out = ctr32(xk, false, counter, data);
|
||||
authKey.fill(0);
|
||||
tagMask.fill(0);
|
||||
xk.fill(0);
|
||||
return out;
|
||||
},
|
||||
};
|
||||
});
|
||||
const limit = (name, min, max) => (value) => {
|
||||
if (!Number.isSafeInteger(value) || min > value || value > max)
|
||||
throw new Error(`${name}: invalid value=${value}, must be [${min}..${max}]`);
|
||||
};
|
||||
/**
|
||||
* AES-GCM-SIV: classic AES-GCM with nonce-misuse resistance.
|
||||
* Guarantees that, when a nonce is repeated, the only security loss is that identical
|
||||
* plaintexts will produce identical ciphertexts.
|
||||
* RFC 8452, https://datatracker.ietf.org/doc/html/rfc8452
|
||||
*/
|
||||
export const siv = wrapCipher({ blockSize: 16, nonceLength: 12, tagLength: 16 }, function siv(key, nonce, AAD) {
|
||||
const tagLength = 16;
|
||||
// From RFC 8452: Section 6
|
||||
const AAD_LIMIT = limit('AAD', 0, 2 ** 36);
|
||||
const PLAIN_LIMIT = limit('plaintext', 0, 2 ** 36);
|
||||
const NONCE_LIMIT = limit('nonce', 12, 12);
|
||||
const CIPHER_LIMIT = limit('ciphertext', 16, 2 ** 36 + 16);
|
||||
abytes(nonce);
|
||||
NONCE_LIMIT(nonce.length);
|
||||
if (AAD) {
|
||||
abytes(AAD);
|
||||
AAD_LIMIT(AAD.length);
|
||||
}
|
||||
function deriveKeys() {
|
||||
const len = key.length;
|
||||
if (len !== 16 && len !== 24 && len !== 32)
|
||||
throw new Error(`key length must be 16, 24 or 32 bytes, got: ${len} bytes`);
|
||||
const xk = expandKeyLE(key);
|
||||
const encKey = new Uint8Array(len);
|
||||
const authKey = new Uint8Array(16);
|
||||
const n32 = u32(nonce);
|
||||
// prettier-ignore
|
||||
let s0 = 0, s1 = n32[0], s2 = n32[1], s3 = n32[2];
|
||||
let counter = 0;
|
||||
for (const derivedKey of [authKey, encKey].map(u32)) {
|
||||
const d32 = u32(derivedKey);
|
||||
for (let i = 0; i < d32.length; i += 2) {
|
||||
// aes(u32le(0) || nonce)[:8] || aes(u32le(1) || nonce)[:8] ...
|
||||
const { s0: o0, s1: o1 } = encrypt(xk, s0, s1, s2, s3);
|
||||
d32[i + 0] = o0;
|
||||
d32[i + 1] = o1;
|
||||
s0 = ++counter; // increment counter inside state
|
||||
}
|
||||
}
|
||||
xk.fill(0);
|
||||
return { authKey, encKey: expandKeyLE(encKey) };
|
||||
}
|
||||
function _computeTag(encKey, authKey, data) {
|
||||
const tag = computeTag(polyval, true, authKey, data, AAD);
|
||||
// Compute the expected tag by XORing S_s and the nonce, clearing the
|
||||
// most significant bit of the last byte and encrypting with the
|
||||
// message-encryption key.
|
||||
for (let i = 0; i < 12; i++)
|
||||
tag[i] ^= nonce[i];
|
||||
tag[15] &= 0x7f; // Clear the highest bit
|
||||
// encrypt tag as block
|
||||
const t32 = u32(tag);
|
||||
// prettier-ignore
|
||||
let s0 = t32[0], s1 = t32[1], s2 = t32[2], s3 = t32[3];
|
||||
({ s0, s1, s2, s3 } = encrypt(encKey, s0, s1, s2, s3));
|
||||
(t32[0] = s0), (t32[1] = s1), (t32[2] = s2), (t32[3] = s3);
|
||||
return tag;
|
||||
}
|
||||
// actual decrypt/encrypt of message.
|
||||
function processSiv(encKey, tag, input) {
|
||||
let block = tag.slice();
|
||||
block[15] |= 0x80; // Force highest bit
|
||||
return ctr32(encKey, true, block, input);
|
||||
}
|
||||
return {
|
||||
encrypt: (plaintext) => {
|
||||
abytes(plaintext);
|
||||
PLAIN_LIMIT(plaintext.length);
|
||||
const { encKey, authKey } = deriveKeys();
|
||||
const tag = _computeTag(encKey, authKey, plaintext);
|
||||
const out = new Uint8Array(plaintext.length + tagLength);
|
||||
out.set(tag, plaintext.length);
|
||||
out.set(processSiv(encKey, tag, plaintext));
|
||||
encKey.fill(0);
|
||||
authKey.fill(0);
|
||||
return out;
|
||||
},
|
||||
decrypt: (ciphertext) => {
|
||||
abytes(ciphertext);
|
||||
CIPHER_LIMIT(ciphertext.length);
|
||||
const tag = ciphertext.subarray(-tagLength);
|
||||
const { encKey, authKey } = deriveKeys();
|
||||
const plaintext = processSiv(encKey, tag, ciphertext.subarray(0, -tagLength));
|
||||
const expectedTag = _computeTag(encKey, authKey, plaintext);
|
||||
encKey.fill(0);
|
||||
authKey.fill(0);
|
||||
if (!equalBytes(tag, expectedTag))
|
||||
throw new Error('invalid polyval tag');
|
||||
return plaintext;
|
||||
},
|
||||
};
|
||||
});
|
||||
function isBytes32(a) {
|
||||
return (a != null &&
|
||||
typeof a === 'object' &&
|
||||
(a instanceof Uint32Array || a.constructor.name === 'Uint32Array'));
|
||||
}
|
||||
function encryptBlock(xk, block) {
|
||||
abytes(block, 16);
|
||||
if (!isBytes32(xk))
|
||||
throw new Error('_encryptBlock accepts result of expandKeyLE');
|
||||
const b32 = u32(block);
|
||||
let { s0, s1, s2, s3 } = encrypt(xk, b32[0], b32[1], b32[2], b32[3]);
|
||||
(b32[0] = s0), (b32[1] = s1), (b32[2] = s2), (b32[3] = s3);
|
||||
return block;
|
||||
}
|
||||
function decryptBlock(xk, block) {
|
||||
abytes(block, 16);
|
||||
if (!isBytes32(xk))
|
||||
throw new Error('_decryptBlock accepts result of expandKeyLE');
|
||||
const b32 = u32(block);
|
||||
let { s0, s1, s2, s3 } = decrypt(xk, b32[0], b32[1], b32[2], b32[3]);
|
||||
(b32[0] = s0), (b32[1] = s1), (b32[2] = s2), (b32[3] = s3);
|
||||
return block;
|
||||
}
|
||||
// Highly unsafe private functions for implementing new modes or ciphers based on AES
|
||||
// Can change at any time, no API guarantees
|
||||
export const unsafe = {
|
||||
expandKeyLE,
|
||||
expandKeyDecLE,
|
||||
encrypt,
|
||||
decrypt,
|
||||
encryptBlock,
|
||||
decryptBlock,
|
||||
ctrCounter,
|
||||
ctr32,
|
||||
};
|
||||
//# sourceMappingURL=aes.js.map
|
||||
1
thrower_daemon/node_modules/@noble/ciphers/esm/aes.js.map
generated
vendored
Normal file
1
thrower_daemon/node_modules/@noble/ciphers/esm/aes.js.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
318
thrower_daemon/node_modules/@noble/ciphers/esm/chacha.js
generated
vendored
Normal file
318
thrower_daemon/node_modules/@noble/ciphers/esm/chacha.js
generated
vendored
Normal file
@@ -0,0 +1,318 @@
|
||||
// prettier-ignore
|
||||
import { wrapCipher, createView, equalBytes, setBigUint64, } from './utils.js';
|
||||
import { poly1305 } from './_poly1305.js';
|
||||
import { createCipher, rotl } from './_arx.js';
|
||||
import { bytes as abytes } from './_assert.js';
|
||||
// ChaCha20 stream cipher was released in 2008. ChaCha aims to increase
|
||||
// the diffusion per round, but had slightly less cryptanalysis.
|
||||
// https://cr.yp.to/chacha.html, http://cr.yp.to/chacha/chacha-20080128.pdf
|
||||
/**
|
||||
* ChaCha core function.
|
||||
*/
|
||||
// prettier-ignore
|
||||
function chachaCore(s, k, n, out, cnt, rounds = 20) {
|
||||
let y00 = s[0], y01 = s[1], y02 = s[2], y03 = s[3], // "expa" "nd 3" "2-by" "te k"
|
||||
y04 = k[0], y05 = k[1], y06 = k[2], y07 = k[3], // Key Key Key Key
|
||||
y08 = k[4], y09 = k[5], y10 = k[6], y11 = k[7], // Key Key Key Key
|
||||
y12 = cnt, y13 = n[0], y14 = n[1], y15 = n[2]; // Counter Counter Nonce Nonce
|
||||
// Save state to temporary variables
|
||||
let x00 = y00, x01 = y01, x02 = y02, x03 = y03, x04 = y04, x05 = y05, x06 = y06, x07 = y07, x08 = y08, x09 = y09, x10 = y10, x11 = y11, x12 = y12, x13 = y13, x14 = y14, x15 = y15;
|
||||
for (let r = 0; r < rounds; r += 2) {
|
||||
x00 = (x00 + x04) | 0;
|
||||
x12 = rotl(x12 ^ x00, 16);
|
||||
x08 = (x08 + x12) | 0;
|
||||
x04 = rotl(x04 ^ x08, 12);
|
||||
x00 = (x00 + x04) | 0;
|
||||
x12 = rotl(x12 ^ x00, 8);
|
||||
x08 = (x08 + x12) | 0;
|
||||
x04 = rotl(x04 ^ x08, 7);
|
||||
x01 = (x01 + x05) | 0;
|
||||
x13 = rotl(x13 ^ x01, 16);
|
||||
x09 = (x09 + x13) | 0;
|
||||
x05 = rotl(x05 ^ x09, 12);
|
||||
x01 = (x01 + x05) | 0;
|
||||
x13 = rotl(x13 ^ x01, 8);
|
||||
x09 = (x09 + x13) | 0;
|
||||
x05 = rotl(x05 ^ x09, 7);
|
||||
x02 = (x02 + x06) | 0;
|
||||
x14 = rotl(x14 ^ x02, 16);
|
||||
x10 = (x10 + x14) | 0;
|
||||
x06 = rotl(x06 ^ x10, 12);
|
||||
x02 = (x02 + x06) | 0;
|
||||
x14 = rotl(x14 ^ x02, 8);
|
||||
x10 = (x10 + x14) | 0;
|
||||
x06 = rotl(x06 ^ x10, 7);
|
||||
x03 = (x03 + x07) | 0;
|
||||
x15 = rotl(x15 ^ x03, 16);
|
||||
x11 = (x11 + x15) | 0;
|
||||
x07 = rotl(x07 ^ x11, 12);
|
||||
x03 = (x03 + x07) | 0;
|
||||
x15 = rotl(x15 ^ x03, 8);
|
||||
x11 = (x11 + x15) | 0;
|
||||
x07 = rotl(x07 ^ x11, 7);
|
||||
x00 = (x00 + x05) | 0;
|
||||
x15 = rotl(x15 ^ x00, 16);
|
||||
x10 = (x10 + x15) | 0;
|
||||
x05 = rotl(x05 ^ x10, 12);
|
||||
x00 = (x00 + x05) | 0;
|
||||
x15 = rotl(x15 ^ x00, 8);
|
||||
x10 = (x10 + x15) | 0;
|
||||
x05 = rotl(x05 ^ x10, 7);
|
||||
x01 = (x01 + x06) | 0;
|
||||
x12 = rotl(x12 ^ x01, 16);
|
||||
x11 = (x11 + x12) | 0;
|
||||
x06 = rotl(x06 ^ x11, 12);
|
||||
x01 = (x01 + x06) | 0;
|
||||
x12 = rotl(x12 ^ x01, 8);
|
||||
x11 = (x11 + x12) | 0;
|
||||
x06 = rotl(x06 ^ x11, 7);
|
||||
x02 = (x02 + x07) | 0;
|
||||
x13 = rotl(x13 ^ x02, 16);
|
||||
x08 = (x08 + x13) | 0;
|
||||
x07 = rotl(x07 ^ x08, 12);
|
||||
x02 = (x02 + x07) | 0;
|
||||
x13 = rotl(x13 ^ x02, 8);
|
||||
x08 = (x08 + x13) | 0;
|
||||
x07 = rotl(x07 ^ x08, 7);
|
||||
x03 = (x03 + x04) | 0;
|
||||
x14 = rotl(x14 ^ x03, 16);
|
||||
x09 = (x09 + x14) | 0;
|
||||
x04 = rotl(x04 ^ x09, 12);
|
||||
x03 = (x03 + x04) | 0;
|
||||
x14 = rotl(x14 ^ x03, 8);
|
||||
x09 = (x09 + x14) | 0;
|
||||
x04 = rotl(x04 ^ x09, 7);
|
||||
}
|
||||
// Write output
|
||||
let oi = 0;
|
||||
out[oi++] = (y00 + x00) | 0;
|
||||
out[oi++] = (y01 + x01) | 0;
|
||||
out[oi++] = (y02 + x02) | 0;
|
||||
out[oi++] = (y03 + x03) | 0;
|
||||
out[oi++] = (y04 + x04) | 0;
|
||||
out[oi++] = (y05 + x05) | 0;
|
||||
out[oi++] = (y06 + x06) | 0;
|
||||
out[oi++] = (y07 + x07) | 0;
|
||||
out[oi++] = (y08 + x08) | 0;
|
||||
out[oi++] = (y09 + x09) | 0;
|
||||
out[oi++] = (y10 + x10) | 0;
|
||||
out[oi++] = (y11 + x11) | 0;
|
||||
out[oi++] = (y12 + x12) | 0;
|
||||
out[oi++] = (y13 + x13) | 0;
|
||||
out[oi++] = (y14 + x14) | 0;
|
||||
out[oi++] = (y15 + x15) | 0;
|
||||
}
|
||||
/**
|
||||
* hchacha helper method, used primarily in xchacha, to hash
|
||||
* key and nonce into key' and nonce'.
|
||||
* Same as chachaCore, but there doesn't seem to be a way to move the block
|
||||
* out without 25% performance hit.
|
||||
*/
|
||||
// prettier-ignore
|
||||
export function hchacha(s, k, i, o32) {
|
||||
let x00 = s[0], x01 = s[1], x02 = s[2], x03 = s[3], x04 = k[0], x05 = k[1], x06 = k[2], x07 = k[3], x08 = k[4], x09 = k[5], x10 = k[6], x11 = k[7], x12 = i[0], x13 = i[1], x14 = i[2], x15 = i[3];
|
||||
for (let r = 0; r < 20; r += 2) {
|
||||
x00 = (x00 + x04) | 0;
|
||||
x12 = rotl(x12 ^ x00, 16);
|
||||
x08 = (x08 + x12) | 0;
|
||||
x04 = rotl(x04 ^ x08, 12);
|
||||
x00 = (x00 + x04) | 0;
|
||||
x12 = rotl(x12 ^ x00, 8);
|
||||
x08 = (x08 + x12) | 0;
|
||||
x04 = rotl(x04 ^ x08, 7);
|
||||
x01 = (x01 + x05) | 0;
|
||||
x13 = rotl(x13 ^ x01, 16);
|
||||
x09 = (x09 + x13) | 0;
|
||||
x05 = rotl(x05 ^ x09, 12);
|
||||
x01 = (x01 + x05) | 0;
|
||||
x13 = rotl(x13 ^ x01, 8);
|
||||
x09 = (x09 + x13) | 0;
|
||||
x05 = rotl(x05 ^ x09, 7);
|
||||
x02 = (x02 + x06) | 0;
|
||||
x14 = rotl(x14 ^ x02, 16);
|
||||
x10 = (x10 + x14) | 0;
|
||||
x06 = rotl(x06 ^ x10, 12);
|
||||
x02 = (x02 + x06) | 0;
|
||||
x14 = rotl(x14 ^ x02, 8);
|
||||
x10 = (x10 + x14) | 0;
|
||||
x06 = rotl(x06 ^ x10, 7);
|
||||
x03 = (x03 + x07) | 0;
|
||||
x15 = rotl(x15 ^ x03, 16);
|
||||
x11 = (x11 + x15) | 0;
|
||||
x07 = rotl(x07 ^ x11, 12);
|
||||
x03 = (x03 + x07) | 0;
|
||||
x15 = rotl(x15 ^ x03, 8);
|
||||
x11 = (x11 + x15) | 0;
|
||||
x07 = rotl(x07 ^ x11, 7);
|
||||
x00 = (x00 + x05) | 0;
|
||||
x15 = rotl(x15 ^ x00, 16);
|
||||
x10 = (x10 + x15) | 0;
|
||||
x05 = rotl(x05 ^ x10, 12);
|
||||
x00 = (x00 + x05) | 0;
|
||||
x15 = rotl(x15 ^ x00, 8);
|
||||
x10 = (x10 + x15) | 0;
|
||||
x05 = rotl(x05 ^ x10, 7);
|
||||
x01 = (x01 + x06) | 0;
|
||||
x12 = rotl(x12 ^ x01, 16);
|
||||
x11 = (x11 + x12) | 0;
|
||||
x06 = rotl(x06 ^ x11, 12);
|
||||
x01 = (x01 + x06) | 0;
|
||||
x12 = rotl(x12 ^ x01, 8);
|
||||
x11 = (x11 + x12) | 0;
|
||||
x06 = rotl(x06 ^ x11, 7);
|
||||
x02 = (x02 + x07) | 0;
|
||||
x13 = rotl(x13 ^ x02, 16);
|
||||
x08 = (x08 + x13) | 0;
|
||||
x07 = rotl(x07 ^ x08, 12);
|
||||
x02 = (x02 + x07) | 0;
|
||||
x13 = rotl(x13 ^ x02, 8);
|
||||
x08 = (x08 + x13) | 0;
|
||||
x07 = rotl(x07 ^ x08, 7);
|
||||
x03 = (x03 + x04) | 0;
|
||||
x14 = rotl(x14 ^ x03, 16);
|
||||
x09 = (x09 + x14) | 0;
|
||||
x04 = rotl(x04 ^ x09, 12);
|
||||
x03 = (x03 + x04) | 0;
|
||||
x14 = rotl(x14 ^ x03, 8);
|
||||
x09 = (x09 + x14) | 0;
|
||||
x04 = rotl(x04 ^ x09, 7);
|
||||
}
|
||||
let oi = 0;
|
||||
o32[oi++] = x00;
|
||||
o32[oi++] = x01;
|
||||
o32[oi++] = x02;
|
||||
o32[oi++] = x03;
|
||||
o32[oi++] = x12;
|
||||
o32[oi++] = x13;
|
||||
o32[oi++] = x14;
|
||||
o32[oi++] = x15;
|
||||
}
|
||||
/**
|
||||
* Original, non-RFC chacha20 from DJB. 8-byte nonce, 8-byte counter.
|
||||
*/
|
||||
export const chacha20orig = /* @__PURE__ */ createCipher(chachaCore, {
|
||||
counterRight: false,
|
||||
counterLength: 8,
|
||||
allowShortKeys: true,
|
||||
});
|
||||
/**
|
||||
* ChaCha stream cipher. Conforms to RFC 8439 (IETF, TLS). 12-byte nonce, 4-byte counter.
|
||||
* With 12-byte nonce, it's not safe to use fill it with random (CSPRNG), due to collision chance.
|
||||
*/
|
||||
export const chacha20 = /* @__PURE__ */ createCipher(chachaCore, {
|
||||
counterRight: false,
|
||||
counterLength: 4,
|
||||
allowShortKeys: false,
|
||||
});
|
||||
/**
|
||||
* XChaCha eXtended-nonce ChaCha. 24-byte nonce.
|
||||
* With 24-byte nonce, it's safe to use fill it with random (CSPRNG).
|
||||
* https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-xchacha
|
||||
*/
|
||||
export const xchacha20 = /* @__PURE__ */ createCipher(chachaCore, {
|
||||
counterRight: false,
|
||||
counterLength: 8,
|
||||
extendNonceFn: hchacha,
|
||||
allowShortKeys: false,
|
||||
});
|
||||
/**
|
||||
* Reduced 8-round chacha, described in original paper.
|
||||
*/
|
||||
export const chacha8 = /* @__PURE__ */ createCipher(chachaCore, {
|
||||
counterRight: false,
|
||||
counterLength: 4,
|
||||
rounds: 8,
|
||||
});
|
||||
/**
|
||||
* Reduced 12-round chacha, described in original paper.
|
||||
*/
|
||||
export const chacha12 = /* @__PURE__ */ createCipher(chachaCore, {
|
||||
counterRight: false,
|
||||
counterLength: 4,
|
||||
rounds: 12,
|
||||
});
|
||||
const ZEROS16 = /* @__PURE__ */ new Uint8Array(16);
|
||||
// Pad to digest size with zeros
|
||||
const updatePadded = (h, msg) => {
|
||||
h.update(msg);
|
||||
const left = msg.length % 16;
|
||||
if (left)
|
||||
h.update(ZEROS16.subarray(left));
|
||||
};
|
||||
const ZEROS32 = /* @__PURE__ */ new Uint8Array(32);
|
||||
function computeTag(fn, key, nonce, data, AAD) {
|
||||
const authKey = fn(key, nonce, ZEROS32);
|
||||
const h = poly1305.create(authKey);
|
||||
if (AAD)
|
||||
updatePadded(h, AAD);
|
||||
updatePadded(h, data);
|
||||
const num = new Uint8Array(16);
|
||||
const view = createView(num);
|
||||
setBigUint64(view, 0, BigInt(AAD ? AAD.length : 0), true);
|
||||
setBigUint64(view, 8, BigInt(data.length), true);
|
||||
h.update(num);
|
||||
const res = h.digest();
|
||||
authKey.fill(0);
|
||||
return res;
|
||||
}
|
||||
/**
|
||||
* AEAD algorithm from RFC 8439.
|
||||
* Salsa20 and chacha (RFC 8439) use poly1305 differently.
|
||||
* We could have composed them similar to:
|
||||
* https://github.com/paulmillr/scure-base/blob/b266c73dde977b1dd7ef40ef7a23cc15aab526b3/index.ts#L250
|
||||
* But it's hard because of authKey:
|
||||
* In salsa20, authKey changes position in salsa stream.
|
||||
* In chacha, authKey can't be computed inside computeTag, it modifies the counter.
|
||||
*/
|
||||
export const _poly1305_aead = (xorStream) => (key, nonce, AAD) => {
|
||||
const tagLength = 16;
|
||||
abytes(key, 32);
|
||||
abytes(nonce);
|
||||
return {
|
||||
encrypt: (plaintext, output) => {
|
||||
const plength = plaintext.length;
|
||||
const clength = plength + tagLength;
|
||||
if (output) {
|
||||
abytes(output, clength);
|
||||
}
|
||||
else {
|
||||
output = new Uint8Array(clength);
|
||||
}
|
||||
xorStream(key, nonce, plaintext, output, 1);
|
||||
const tag = computeTag(xorStream, key, nonce, output.subarray(0, -tagLength), AAD);
|
||||
output.set(tag, plength); // append tag
|
||||
return output;
|
||||
},
|
||||
decrypt: (ciphertext, output) => {
|
||||
const clength = ciphertext.length;
|
||||
const plength = clength - tagLength;
|
||||
if (clength < tagLength)
|
||||
throw new Error(`encrypted data must be at least ${tagLength} bytes`);
|
||||
if (output) {
|
||||
abytes(output, plength);
|
||||
}
|
||||
else {
|
||||
output = new Uint8Array(plength);
|
||||
}
|
||||
const data = ciphertext.subarray(0, -tagLength);
|
||||
const passedTag = ciphertext.subarray(-tagLength);
|
||||
const tag = computeTag(xorStream, key, nonce, data, AAD);
|
||||
if (!equalBytes(passedTag, tag))
|
||||
throw new Error('invalid tag');
|
||||
xorStream(key, nonce, data, output, 1);
|
||||
return output;
|
||||
},
|
||||
};
|
||||
};
|
||||
/**
|
||||
* ChaCha20-Poly1305 from RFC 8439.
|
||||
* With 12-byte nonce, it's not safe to use fill it with random (CSPRNG), due to collision chance.
|
||||
*/
|
||||
export const chacha20poly1305 = /* @__PURE__ */ wrapCipher({ blockSize: 64, nonceLength: 12, tagLength: 16 }, _poly1305_aead(chacha20));
|
||||
/**
|
||||
* XChaCha20-Poly1305 extended-nonce chacha.
|
||||
* https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-xchacha
|
||||
* With 24-byte nonce, it's safe to use fill it with random (CSPRNG).
|
||||
*/
|
||||
export const xchacha20poly1305 = /* @__PURE__ */ wrapCipher({ blockSize: 64, nonceLength: 24, tagLength: 16 }, _poly1305_aead(xchacha20));
|
||||
//# sourceMappingURL=chacha.js.map
|
||||
1
thrower_daemon/node_modules/@noble/ciphers/esm/chacha.js.map
generated
vendored
Normal file
1
thrower_daemon/node_modules/@noble/ciphers/esm/chacha.js.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
12
thrower_daemon/node_modules/@noble/ciphers/esm/crypto.js
generated
vendored
Normal file
12
thrower_daemon/node_modules/@noble/ciphers/esm/crypto.js
generated
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
const cr = typeof globalThis === 'object' && 'crypto' in globalThis ? globalThis.crypto : undefined;
|
||||
export function randomBytes(bytesLength = 32) {
|
||||
if (cr && typeof cr.getRandomValues === 'function')
|
||||
return cr.getRandomValues(new Uint8Array(bytesLength));
|
||||
throw new Error('crypto.getRandomValues must be defined');
|
||||
}
|
||||
export function getWebcryptoSubtle() {
|
||||
if (cr && typeof cr.subtle === 'object' && cr.subtle != null)
|
||||
return cr.subtle;
|
||||
throw new Error('crypto.subtle must be defined');
|
||||
}
|
||||
//# sourceMappingURL=crypto.js.map
|
||||
1
thrower_daemon/node_modules/@noble/ciphers/esm/crypto.js.map
generated
vendored
Normal file
1
thrower_daemon/node_modules/@noble/ciphers/esm/crypto.js.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"crypto.js","sourceRoot":"","sources":["../src/crypto.ts"],"names":[],"mappings":"AAGA,MAAM,EAAE,GAAG,OAAO,UAAU,KAAK,QAAQ,IAAI,QAAQ,IAAI,UAAU,CAAC,CAAC,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC;AAEpG,MAAM,UAAU,WAAW,CAAC,WAAW,GAAG,EAAE;IAC1C,IAAI,EAAE,IAAI,OAAO,EAAE,CAAC,eAAe,KAAK,UAAU;QAChD,OAAO,EAAE,CAAC,eAAe,CAAC,IAAI,UAAU,CAAC,WAAW,CAAC,CAAC,CAAC;IACzD,MAAM,IAAI,KAAK,CAAC,wCAAwC,CAAC,CAAC;AAC5D,CAAC;AAED,MAAM,UAAU,kBAAkB;IAChC,IAAI,EAAE,IAAI,OAAO,EAAE,CAAC,MAAM,KAAK,QAAQ,IAAI,EAAE,CAAC,MAAM,IAAI,IAAI;QAAE,OAAO,EAAE,CAAC,MAAM,CAAC;IAC/E,MAAM,IAAI,KAAK,CAAC,+BAA+B,CAAC,CAAC;AACnD,CAAC"}
|
||||
17
thrower_daemon/node_modules/@noble/ciphers/esm/cryptoNode.js
generated
vendored
Normal file
17
thrower_daemon/node_modules/@noble/ciphers/esm/cryptoNode.js
generated
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
// We use WebCrypto aka globalThis.crypto, which exists in browsers and node.js 16+.
|
||||
// See utils.ts for details.
|
||||
// The file will throw on node.js 14 and earlier.
|
||||
// @ts-ignore
|
||||
import * as nc from 'node:crypto';
|
||||
const cr = nc && typeof nc === 'object' && 'webcrypto' in nc ? nc.webcrypto : undefined;
|
||||
export function randomBytes(bytesLength = 32) {
|
||||
if (cr && typeof cr.getRandomValues === 'function')
|
||||
return cr.getRandomValues(new Uint8Array(bytesLength));
|
||||
throw new Error('crypto.getRandomValues must be defined');
|
||||
}
|
||||
export function getWebcryptoSubtle() {
|
||||
if (cr && typeof cr.subtle === 'object' && cr.subtle != null)
|
||||
return cr.subtle;
|
||||
throw new Error('crypto.subtle must be defined');
|
||||
}
|
||||
//# sourceMappingURL=cryptoNode.js.map
|
||||
1
thrower_daemon/node_modules/@noble/ciphers/esm/cryptoNode.js.map
generated
vendored
Normal file
1
thrower_daemon/node_modules/@noble/ciphers/esm/cryptoNode.js.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"cryptoNode.js","sourceRoot":"","sources":["../src/cryptoNode.ts"],"names":[],"mappings":"AAAA,oFAAoF;AACpF,4BAA4B;AAC5B,iDAAiD;AACjD,aAAa;AACb,OAAO,KAAK,EAAE,MAAM,aAAa,CAAC;AAClC,MAAM,EAAE,GAAG,EAAE,IAAI,OAAO,EAAE,KAAK,QAAQ,IAAI,WAAW,IAAI,EAAE,CAAC,CAAC,CAAE,EAAE,CAAC,SAAiB,CAAC,CAAC,CAAC,SAAS,CAAC;AAEjG,MAAM,UAAU,WAAW,CAAC,WAAW,GAAG,EAAE;IAC1C,IAAI,EAAE,IAAI,OAAO,EAAE,CAAC,eAAe,KAAK,UAAU;QAChD,OAAO,EAAE,CAAC,eAAe,CAAC,IAAI,UAAU,CAAC,WAAW,CAAC,CAAC,CAAC;IACzD,MAAM,IAAI,KAAK,CAAC,wCAAwC,CAAC,CAAC;AAC5D,CAAC;AAED,MAAM,UAAU,kBAAkB;IAChC,IAAI,EAAE,IAAI,OAAO,EAAE,CAAC,MAAM,KAAK,QAAQ,IAAI,EAAE,CAAC,MAAM,IAAI,IAAI;QAAE,OAAO,EAAE,CAAC,MAAM,CAAC;IAC/E,MAAM,IAAI,KAAK,CAAC,+BAA+B,CAAC,CAAC;AACnD,CAAC"}
|
||||
149
thrower_daemon/node_modules/@noble/ciphers/esm/ff1.js
generated
vendored
Normal file
149
thrower_daemon/node_modules/@noble/ciphers/esm/ff1.js
generated
vendored
Normal file
@@ -0,0 +1,149 @@
|
||||
import { bytesToNumberBE, numberToBytesBE } from './utils.js';
|
||||
import { unsafe } from './aes.js';
|
||||
// NOTE: no point in inlining encrypt instead of encryptBlock, since BigInt stuff will be slow
|
||||
const { expandKeyLE, encryptBlock } = unsafe;
|
||||
// Format-preserving encryption algorithm (FPE-FF1) specified in NIST Special Publication 800-38G.
|
||||
// https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-38G.pdf
|
||||
const BLOCK_LEN = 16;
|
||||
function mod(a, b) {
|
||||
const result = a % b;
|
||||
return result >= 0 ? result : b + result;
|
||||
}
|
||||
function NUMradix(radix, data) {
|
||||
let res = BigInt(0);
|
||||
for (let i of data)
|
||||
res = res * BigInt(radix) + BigInt(i);
|
||||
return res;
|
||||
}
|
||||
function getRound(radix, key, tweak, x) {
|
||||
if (radix > 2 ** 16 - 1)
|
||||
throw new Error(`Invalid radix: ${radix}`);
|
||||
// radix**minlen ≥ 100
|
||||
const minLen = Math.ceil(Math.log(100) / Math.log(radix));
|
||||
const maxLen = 2 ** 32 - 1;
|
||||
// 2 ≤ minlen ≤ maxlen < 2**32
|
||||
if (2 > minLen || minLen > maxLen || maxLen >= 2 ** 32)
|
||||
throw new Error('Invalid radix: 2 ≤ minlen ≤ maxlen < 2**32');
|
||||
if (x.length < minLen || x.length > maxLen)
|
||||
throw new Error('X is outside minLen..maxLen bounds');
|
||||
const u = Math.floor(x.length / 2);
|
||||
const v = x.length - u;
|
||||
const b = Math.ceil(Math.ceil(v * Math.log2(radix)) / 8);
|
||||
const d = 4 * Math.ceil(b / 4) + 4;
|
||||
const padding = mod(-tweak.length - b - 1, 16);
|
||||
// P = [1]1 || [2]1 || [1]1 || [radix]3 || [10]1 || [u mod 256]1 || [n]4 || [t]4.
|
||||
const P = new Uint8Array([1, 2, 1, 0, 0, 0, 10, u, 0, 0, 0, 0, 0, 0, 0, 0]);
|
||||
const view = new DataView(P.buffer);
|
||||
view.setUint16(4, radix, false);
|
||||
view.setUint32(8, x.length, false);
|
||||
view.setUint32(12, tweak.length, false);
|
||||
// Q = T || [0](−t−b−1) mod 16 || [i]1 || [NUMradix(B)]b.
|
||||
const PQ = new Uint8Array(P.length + tweak.length + padding + 1 + b);
|
||||
PQ.set(P);
|
||||
P.fill(0);
|
||||
PQ.set(tweak, P.length);
|
||||
const xk = expandKeyLE(key);
|
||||
const round = (A, B, i, decrypt = false) => {
|
||||
// Q = ... || [i]1 || [NUMradix(B)]b.
|
||||
PQ[PQ.length - b - 1] = i;
|
||||
if (b)
|
||||
PQ.set(numberToBytesBE(NUMradix(radix, B), b), PQ.length - b);
|
||||
// PRF
|
||||
let r = new Uint8Array(16);
|
||||
for (let j = 0; j < PQ.length / BLOCK_LEN; j++) {
|
||||
for (let i = 0; i < BLOCK_LEN; i++)
|
||||
r[i] ^= PQ[j * BLOCK_LEN + i];
|
||||
encryptBlock(xk, r);
|
||||
}
|
||||
// Let S be the first d bytes of the following string of ⎡d/16⎤ blocks:
|
||||
// R || CIPHK(R ⊕[1]16) || CIPHK(R ⊕[2]16) ...CIPHK(R ⊕[⎡d / 16⎤ – 1]16).
|
||||
let s = Array.from(r);
|
||||
for (let j = 1; s.length < d; j++) {
|
||||
const block = numberToBytesBE(BigInt(j), 16);
|
||||
for (let k = 0; k < BLOCK_LEN; k++)
|
||||
block[k] ^= r[k];
|
||||
s.push(...Array.from(encryptBlock(xk, block)));
|
||||
}
|
||||
let y = bytesToNumberBE(Uint8Array.from(s.slice(0, d)));
|
||||
s.fill(0);
|
||||
if (decrypt)
|
||||
y = -y;
|
||||
const m = i % 2 === 0 ? u : v;
|
||||
let c = mod(NUMradix(radix, A) + y, BigInt(radix) ** BigInt(m));
|
||||
// STR(radix, m, c)
|
||||
const C = Array(m).fill(0);
|
||||
for (let i = 0; i < m; i++, c /= BigInt(radix))
|
||||
C[m - 1 - i] = Number(c % BigInt(radix));
|
||||
A.fill(0);
|
||||
A = B;
|
||||
B = C;
|
||||
return [A, B];
|
||||
};
|
||||
const destroy = () => {
|
||||
xk.fill(0);
|
||||
PQ.fill(0);
|
||||
};
|
||||
return { u, round, destroy };
|
||||
}
|
||||
const EMPTY_BUF = new Uint8Array([]);
|
||||
export function FF1(radix, key, tweak = EMPTY_BUF) {
|
||||
const PQ = getRound.bind(null, radix, key, tweak);
|
||||
return {
|
||||
encrypt(x) {
|
||||
const { u, round, destroy } = PQ(x);
|
||||
let [A, B] = [x.slice(0, u), x.slice(u)];
|
||||
for (let i = 0; i < 10; i++)
|
||||
[A, B] = round(A, B, i);
|
||||
destroy();
|
||||
const res = A.concat(B);
|
||||
A.fill(0);
|
||||
B.fill(0);
|
||||
return res;
|
||||
},
|
||||
decrypt(x) {
|
||||
const { u, round, destroy } = PQ(x);
|
||||
// The FF1.Decrypt algorithm is similar to the FF1.Encrypt algorithm;
|
||||
// the differences are in Step 6, where:
|
||||
// 1) the order of the indices is reversed,
|
||||
// 2) the roles of A and B are swapped
|
||||
// 3) modular addition is replaced by modular subtraction, in Step 6vi.
|
||||
let [B, A] = [x.slice(0, u), x.slice(u)];
|
||||
for (let i = 9; i >= 0; i--)
|
||||
[A, B] = round(A, B, i, true);
|
||||
destroy();
|
||||
const res = B.concat(A);
|
||||
A.fill(0);
|
||||
B.fill(0);
|
||||
return res;
|
||||
},
|
||||
};
|
||||
}
|
||||
// Binary string which encodes each byte in little-endian byte order
|
||||
const binLE = {
|
||||
encode(bytes) {
|
||||
const x = [];
|
||||
for (let i = 0; i < bytes.length; i++) {
|
||||
for (let j = 0, tmp = bytes[i]; j < 8; j++, tmp >>= 1)
|
||||
x.push(tmp & 1);
|
||||
}
|
||||
return x;
|
||||
},
|
||||
decode(b) {
|
||||
if (b.length % 8)
|
||||
throw new Error('Invalid binary string');
|
||||
const res = new Uint8Array(b.length / 8);
|
||||
for (let i = 0, j = 0; i < res.length; i++) {
|
||||
res[i] = b[j++] | (b[j++] << 1) | (b[j++] << 2) | (b[j++] << 3);
|
||||
res[i] |= (b[j++] << 4) | (b[j++] << 5) | (b[j++] << 6) | (b[j++] << 7);
|
||||
}
|
||||
return res;
|
||||
},
|
||||
};
|
||||
export function BinaryFF1(key, tweak = EMPTY_BUF) {
|
||||
const ff1 = FF1(2, key, tweak);
|
||||
return {
|
||||
encrypt: (x) => binLE.decode(ff1.encrypt(binLE.encode(x))),
|
||||
decrypt: (x) => binLE.decode(ff1.decrypt(binLE.encode(x))),
|
||||
};
|
||||
}
|
||||
//# sourceMappingURL=ff1.js.map
|
||||
1
thrower_daemon/node_modules/@noble/ciphers/esm/ff1.js.map
generated
vendored
Normal file
1
thrower_daemon/node_modules/@noble/ciphers/esm/ff1.js.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
3
thrower_daemon/node_modules/@noble/ciphers/esm/index.js
generated
vendored
Normal file
3
thrower_daemon/node_modules/@noble/ciphers/esm/index.js
generated
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
throw new Error('noble-ciphers have no entry-point: consult README for usage');
|
||||
export {};
|
||||
//# sourceMappingURL=index.js.map
|
||||
1
thrower_daemon/node_modules/@noble/ciphers/esm/index.js.map
generated
vendored
Normal file
1
thrower_daemon/node_modules/@noble/ciphers/esm/index.js.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,MAAM,IAAI,KAAK,CAAC,6DAA6D,CAAC,CAAC"}
|
||||
11
thrower_daemon/node_modules/@noble/ciphers/esm/package.json
generated
vendored
Normal file
11
thrower_daemon/node_modules/@noble/ciphers/esm/package.json
generated
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"type": "module",
|
||||
"sideEffects": false,
|
||||
"browser": {
|
||||
"node:crypto": false
|
||||
},
|
||||
"node": {
|
||||
"./crypto.js": "./esm/cryptoNode.js",
|
||||
"./crypto": "./esm/cryptoNode.js"
|
||||
}
|
||||
}
|
||||
205
thrower_daemon/node_modules/@noble/ciphers/esm/salsa.js
generated
vendored
Normal file
205
thrower_daemon/node_modules/@noble/ciphers/esm/salsa.js
generated
vendored
Normal file
@@ -0,0 +1,205 @@
|
||||
import { bytes as abytes } from './_assert.js';
|
||||
import { createCipher, rotl } from './_arx.js';
|
||||
import { poly1305 } from './_poly1305.js';
|
||||
import { wrapCipher, equalBytes } from './utils.js';
|
||||
// Salsa20 stream cipher was released in 2005.
|
||||
// Salsa's goal was to implement AES replacement that does not rely on S-Boxes,
|
||||
// which are hard to implement in a constant-time manner.
|
||||
// https://cr.yp.to/snuffle.html, https://cr.yp.to/snuffle/salsafamily-20071225.pdf
|
||||
/**
|
||||
* Salsa20 core function.
|
||||
*/
|
||||
// prettier-ignore
|
||||
function salsaCore(s, k, n, out, cnt, rounds = 20) {
|
||||
// Based on https://cr.yp.to/salsa20.html
|
||||
let y00 = s[0], y01 = k[0], y02 = k[1], y03 = k[2], // "expa" Key Key Key
|
||||
y04 = k[3], y05 = s[1], y06 = n[0], y07 = n[1], // Key "nd 3" Nonce Nonce
|
||||
y08 = cnt, y09 = 0, y10 = s[2], y11 = k[4], // Pos. Pos. "2-by" Key
|
||||
y12 = k[5], y13 = k[6], y14 = k[7], y15 = s[3]; // Key Key Key "te k"
|
||||
// Save state to temporary variables
|
||||
let x00 = y00, x01 = y01, x02 = y02, x03 = y03, x04 = y04, x05 = y05, x06 = y06, x07 = y07, x08 = y08, x09 = y09, x10 = y10, x11 = y11, x12 = y12, x13 = y13, x14 = y14, x15 = y15;
|
||||
for (let r = 0; r < rounds; r += 2) {
|
||||
x04 ^= rotl(x00 + x12 | 0, 7);
|
||||
x08 ^= rotl(x04 + x00 | 0, 9);
|
||||
x12 ^= rotl(x08 + x04 | 0, 13);
|
||||
x00 ^= rotl(x12 + x08 | 0, 18);
|
||||
x09 ^= rotl(x05 + x01 | 0, 7);
|
||||
x13 ^= rotl(x09 + x05 | 0, 9);
|
||||
x01 ^= rotl(x13 + x09 | 0, 13);
|
||||
x05 ^= rotl(x01 + x13 | 0, 18);
|
||||
x14 ^= rotl(x10 + x06 | 0, 7);
|
||||
x02 ^= rotl(x14 + x10 | 0, 9);
|
||||
x06 ^= rotl(x02 + x14 | 0, 13);
|
||||
x10 ^= rotl(x06 + x02 | 0, 18);
|
||||
x03 ^= rotl(x15 + x11 | 0, 7);
|
||||
x07 ^= rotl(x03 + x15 | 0, 9);
|
||||
x11 ^= rotl(x07 + x03 | 0, 13);
|
||||
x15 ^= rotl(x11 + x07 | 0, 18);
|
||||
x01 ^= rotl(x00 + x03 | 0, 7);
|
||||
x02 ^= rotl(x01 + x00 | 0, 9);
|
||||
x03 ^= rotl(x02 + x01 | 0, 13);
|
||||
x00 ^= rotl(x03 + x02 | 0, 18);
|
||||
x06 ^= rotl(x05 + x04 | 0, 7);
|
||||
x07 ^= rotl(x06 + x05 | 0, 9);
|
||||
x04 ^= rotl(x07 + x06 | 0, 13);
|
||||
x05 ^= rotl(x04 + x07 | 0, 18);
|
||||
x11 ^= rotl(x10 + x09 | 0, 7);
|
||||
x08 ^= rotl(x11 + x10 | 0, 9);
|
||||
x09 ^= rotl(x08 + x11 | 0, 13);
|
||||
x10 ^= rotl(x09 + x08 | 0, 18);
|
||||
x12 ^= rotl(x15 + x14 | 0, 7);
|
||||
x13 ^= rotl(x12 + x15 | 0, 9);
|
||||
x14 ^= rotl(x13 + x12 | 0, 13);
|
||||
x15 ^= rotl(x14 + x13 | 0, 18);
|
||||
}
|
||||
// Write output
|
||||
let oi = 0;
|
||||
out[oi++] = (y00 + x00) | 0;
|
||||
out[oi++] = (y01 + x01) | 0;
|
||||
out[oi++] = (y02 + x02) | 0;
|
||||
out[oi++] = (y03 + x03) | 0;
|
||||
out[oi++] = (y04 + x04) | 0;
|
||||
out[oi++] = (y05 + x05) | 0;
|
||||
out[oi++] = (y06 + x06) | 0;
|
||||
out[oi++] = (y07 + x07) | 0;
|
||||
out[oi++] = (y08 + x08) | 0;
|
||||
out[oi++] = (y09 + x09) | 0;
|
||||
out[oi++] = (y10 + x10) | 0;
|
||||
out[oi++] = (y11 + x11) | 0;
|
||||
out[oi++] = (y12 + x12) | 0;
|
||||
out[oi++] = (y13 + x13) | 0;
|
||||
out[oi++] = (y14 + x14) | 0;
|
||||
out[oi++] = (y15 + x15) | 0;
|
||||
}
|
||||
/**
|
||||
* hsalsa hashing function, used primarily in xsalsa, to hash
|
||||
* key and nonce into key' and nonce'.
|
||||
* Same as salsaCore, but there doesn't seem to be a way to move the block
|
||||
* out without 25% performance hit.
|
||||
*/
|
||||
// prettier-ignore
|
||||
export function hsalsa(s, k, i, o32) {
|
||||
let x00 = s[0], x01 = k[0], x02 = k[1], x03 = k[2], x04 = k[3], x05 = s[1], x06 = i[0], x07 = i[1], x08 = i[2], x09 = i[3], x10 = s[2], x11 = k[4], x12 = k[5], x13 = k[6], x14 = k[7], x15 = s[3];
|
||||
for (let r = 0; r < 20; r += 2) {
|
||||
x04 ^= rotl(x00 + x12 | 0, 7);
|
||||
x08 ^= rotl(x04 + x00 | 0, 9);
|
||||
x12 ^= rotl(x08 + x04 | 0, 13);
|
||||
x00 ^= rotl(x12 + x08 | 0, 18);
|
||||
x09 ^= rotl(x05 + x01 | 0, 7);
|
||||
x13 ^= rotl(x09 + x05 | 0, 9);
|
||||
x01 ^= rotl(x13 + x09 | 0, 13);
|
||||
x05 ^= rotl(x01 + x13 | 0, 18);
|
||||
x14 ^= rotl(x10 + x06 | 0, 7);
|
||||
x02 ^= rotl(x14 + x10 | 0, 9);
|
||||
x06 ^= rotl(x02 + x14 | 0, 13);
|
||||
x10 ^= rotl(x06 + x02 | 0, 18);
|
||||
x03 ^= rotl(x15 + x11 | 0, 7);
|
||||
x07 ^= rotl(x03 + x15 | 0, 9);
|
||||
x11 ^= rotl(x07 + x03 | 0, 13);
|
||||
x15 ^= rotl(x11 + x07 | 0, 18);
|
||||
x01 ^= rotl(x00 + x03 | 0, 7);
|
||||
x02 ^= rotl(x01 + x00 | 0, 9);
|
||||
x03 ^= rotl(x02 + x01 | 0, 13);
|
||||
x00 ^= rotl(x03 + x02 | 0, 18);
|
||||
x06 ^= rotl(x05 + x04 | 0, 7);
|
||||
x07 ^= rotl(x06 + x05 | 0, 9);
|
||||
x04 ^= rotl(x07 + x06 | 0, 13);
|
||||
x05 ^= rotl(x04 + x07 | 0, 18);
|
||||
x11 ^= rotl(x10 + x09 | 0, 7);
|
||||
x08 ^= rotl(x11 + x10 | 0, 9);
|
||||
x09 ^= rotl(x08 + x11 | 0, 13);
|
||||
x10 ^= rotl(x09 + x08 | 0, 18);
|
||||
x12 ^= rotl(x15 + x14 | 0, 7);
|
||||
x13 ^= rotl(x12 + x15 | 0, 9);
|
||||
x14 ^= rotl(x13 + x12 | 0, 13);
|
||||
x15 ^= rotl(x14 + x13 | 0, 18);
|
||||
}
|
||||
let oi = 0;
|
||||
o32[oi++] = x00;
|
||||
o32[oi++] = x05;
|
||||
o32[oi++] = x10;
|
||||
o32[oi++] = x15;
|
||||
o32[oi++] = x06;
|
||||
o32[oi++] = x07;
|
||||
o32[oi++] = x08;
|
||||
o32[oi++] = x09;
|
||||
}
|
||||
/**
|
||||
* Salsa20 from original paper.
|
||||
* With 12-byte nonce, it's not safe to use fill it with random (CSPRNG), due to collision chance.
|
||||
*/
|
||||
export const salsa20 = /* @__PURE__ */ createCipher(salsaCore, {
|
||||
allowShortKeys: true,
|
||||
counterRight: true,
|
||||
});
|
||||
/**
|
||||
* xsalsa20 eXtended-nonce salsa.
|
||||
* With 24-byte nonce, it's safe to use fill it with random (CSPRNG).
|
||||
*/
|
||||
export const xsalsa20 = /* @__PURE__ */ createCipher(salsaCore, {
|
||||
counterRight: true,
|
||||
extendNonceFn: hsalsa,
|
||||
});
|
||||
/**
|
||||
* xsalsa20-poly1305 eXtended-nonce salsa.
|
||||
* With 24-byte nonce, it's safe to use fill it with random (CSPRNG).
|
||||
* Also known as secretbox from libsodium / nacl.
|
||||
*/
|
||||
export const xsalsa20poly1305 = /* @__PURE__ */ wrapCipher({ blockSize: 64, nonceLength: 24, tagLength: 16 }, (key, nonce) => {
|
||||
const tagLength = 16;
|
||||
abytes(key, 32);
|
||||
abytes(nonce, 24);
|
||||
return {
|
||||
encrypt: (plaintext, output) => {
|
||||
abytes(plaintext);
|
||||
// This is small optimization (calculate auth key with same call as encryption itself) makes it hard
|
||||
// to separate tag calculation and encryption itself, since 32 byte is half-block of salsa (64 byte)
|
||||
const clength = plaintext.length + 32;
|
||||
if (output) {
|
||||
abytes(output, clength);
|
||||
}
|
||||
else {
|
||||
output = new Uint8Array(clength);
|
||||
}
|
||||
output.set(plaintext, 32);
|
||||
xsalsa20(key, nonce, output, output);
|
||||
const authKey = output.subarray(0, 32);
|
||||
const tag = poly1305(output.subarray(32), authKey);
|
||||
// Clean auth key, even though JS provides no guarantees about memory cleaning
|
||||
output.set(tag, tagLength);
|
||||
output.subarray(0, tagLength).fill(0);
|
||||
return output.subarray(tagLength);
|
||||
},
|
||||
decrypt: (ciphertext) => {
|
||||
abytes(ciphertext);
|
||||
const clength = ciphertext.length;
|
||||
if (clength < tagLength)
|
||||
throw new Error('encrypted data should be at least 16 bytes');
|
||||
// Create new ciphertext array:
|
||||
// auth tag auth tag from ciphertext ciphertext
|
||||
// [bytes 0..16] [bytes 16..32] [bytes 32..]
|
||||
// 16 instead of 32, because we already have 16 byte tag
|
||||
const ciphertext_ = new Uint8Array(clength + tagLength); // alloc
|
||||
ciphertext_.set(ciphertext, tagLength);
|
||||
// Each xsalsa20 calls to hsalsa to calculate key, but seems not much perf difference
|
||||
// Separate call to calculate authkey, since first bytes contains tag
|
||||
const authKey = xsalsa20(key, nonce, new Uint8Array(32)); // alloc(32)
|
||||
const tag = poly1305(ciphertext_.subarray(32), authKey);
|
||||
if (!equalBytes(ciphertext_.subarray(16, 32), tag))
|
||||
throw new Error('invalid tag');
|
||||
const plaintext = xsalsa20(key, nonce, ciphertext_); // alloc
|
||||
// Clean auth key, even though JS provides no guarantees about memory cleaning
|
||||
plaintext.subarray(0, 32).fill(0);
|
||||
authKey.fill(0);
|
||||
return plaintext.subarray(32);
|
||||
},
|
||||
};
|
||||
});
|
||||
/**
|
||||
* Alias to xsalsa20poly1305, for compatibility with libsodium / nacl
|
||||
*/
|
||||
export function secretbox(key, nonce) {
|
||||
const xs = xsalsa20poly1305(key, nonce);
|
||||
return { seal: xs.encrypt, open: xs.decrypt };
|
||||
}
|
||||
//# sourceMappingURL=salsa.js.map
|
||||
1
thrower_daemon/node_modules/@noble/ciphers/esm/salsa.js.map
generated
vendored
Normal file
1
thrower_daemon/node_modules/@noble/ciphers/esm/salsa.js.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
182
thrower_daemon/node_modules/@noble/ciphers/esm/utils.js
generated
vendored
Normal file
182
thrower_daemon/node_modules/@noble/ciphers/esm/utils.js
generated
vendored
Normal file
@@ -0,0 +1,182 @@
|
||||
/*! noble-ciphers - MIT License (c) 2023 Paul Miller (paulmillr.com) */
|
||||
import { bytes as abytes, isBytes } from './_assert.js';
|
||||
// Cast array to different type
|
||||
export const u8 = (arr) => new Uint8Array(arr.buffer, arr.byteOffset, arr.byteLength);
|
||||
export const u16 = (arr) => new Uint16Array(arr.buffer, arr.byteOffset, Math.floor(arr.byteLength / 2));
|
||||
export const u32 = (arr) => new Uint32Array(arr.buffer, arr.byteOffset, Math.floor(arr.byteLength / 4));
|
||||
// Cast array to view
|
||||
export const createView = (arr) => new DataView(arr.buffer, arr.byteOffset, arr.byteLength);
|
||||
// big-endian hardware is rare. Just in case someone still decides to run ciphers:
|
||||
// early-throw an error because we don't support BE yet.
|
||||
export const isLE = new Uint8Array(new Uint32Array([0x11223344]).buffer)[0] === 0x44;
|
||||
if (!isLE)
|
||||
throw new Error('Non little-endian hardware is not supported');
|
||||
// Array where index 0xf0 (240) is mapped to string 'f0'
|
||||
const hexes = /* @__PURE__ */ Array.from({ length: 256 }, (_, i) => i.toString(16).padStart(2, '0'));
|
||||
/**
|
||||
* @example bytesToHex(Uint8Array.from([0xca, 0xfe, 0x01, 0x23])) // 'cafe0123'
|
||||
*/
|
||||
export function bytesToHex(bytes) {
|
||||
abytes(bytes);
|
||||
// pre-caching improves the speed 6x
|
||||
let hex = '';
|
||||
for (let i = 0; i < bytes.length; i++) {
|
||||
hex += hexes[bytes[i]];
|
||||
}
|
||||
return hex;
|
||||
}
|
||||
// We use optimized technique to convert hex string to byte array
|
||||
const asciis = { _0: 48, _9: 57, _A: 65, _F: 70, _a: 97, _f: 102 };
|
||||
function asciiToBase16(char) {
|
||||
if (char >= asciis._0 && char <= asciis._9)
|
||||
return char - asciis._0;
|
||||
if (char >= asciis._A && char <= asciis._F)
|
||||
return char - (asciis._A - 10);
|
||||
if (char >= asciis._a && char <= asciis._f)
|
||||
return char - (asciis._a - 10);
|
||||
return;
|
||||
}
|
||||
/**
|
||||
* @example hexToBytes('cafe0123') // Uint8Array.from([0xca, 0xfe, 0x01, 0x23])
|
||||
*/
|
||||
export function hexToBytes(hex) {
|
||||
if (typeof hex !== 'string')
|
||||
throw new Error('hex string expected, got ' + typeof hex);
|
||||
const hl = hex.length;
|
||||
const al = hl / 2;
|
||||
if (hl % 2)
|
||||
throw new Error('padded hex string expected, got unpadded hex of length ' + hl);
|
||||
const array = new Uint8Array(al);
|
||||
for (let ai = 0, hi = 0; ai < al; ai++, hi += 2) {
|
||||
const n1 = asciiToBase16(hex.charCodeAt(hi));
|
||||
const n2 = asciiToBase16(hex.charCodeAt(hi + 1));
|
||||
if (n1 === undefined || n2 === undefined) {
|
||||
const char = hex[hi] + hex[hi + 1];
|
||||
throw new Error('hex string expected, got non-hex character "' + char + '" at index ' + hi);
|
||||
}
|
||||
array[ai] = n1 * 16 + n2;
|
||||
}
|
||||
return array;
|
||||
}
|
||||
export function hexToNumber(hex) {
|
||||
if (typeof hex !== 'string')
|
||||
throw new Error('hex string expected, got ' + typeof hex);
|
||||
// Big Endian
|
||||
return BigInt(hex === '' ? '0' : `0x${hex}`);
|
||||
}
|
||||
// BE: Big Endian, LE: Little Endian
|
||||
export function bytesToNumberBE(bytes) {
|
||||
return hexToNumber(bytesToHex(bytes));
|
||||
}
|
||||
export function numberToBytesBE(n, len) {
|
||||
return hexToBytes(n.toString(16).padStart(len * 2, '0'));
|
||||
}
|
||||
// There is no setImmediate in browser and setTimeout is slow.
|
||||
// call of async fn will return Promise, which will be fullfiled only on
|
||||
// next scheduler queue processing step and this is exactly what we need.
|
||||
export const nextTick = async () => { };
|
||||
// Returns control to thread each 'tick' ms to avoid blocking
|
||||
export async function asyncLoop(iters, tick, cb) {
|
||||
let ts = Date.now();
|
||||
for (let i = 0; i < iters; i++) {
|
||||
cb(i);
|
||||
// Date.now() is not monotonic, so in case if clock goes backwards we return return control too
|
||||
const diff = Date.now() - ts;
|
||||
if (diff >= 0 && diff < tick)
|
||||
continue;
|
||||
await nextTick();
|
||||
ts += diff;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @example utf8ToBytes('abc') // new Uint8Array([97, 98, 99])
|
||||
*/
|
||||
export function utf8ToBytes(str) {
|
||||
if (typeof str !== 'string')
|
||||
throw new Error(`string expected, got ${typeof str}`);
|
||||
return new Uint8Array(new TextEncoder().encode(str)); // https://bugzil.la/1681809
|
||||
}
|
||||
/**
|
||||
* @example bytesToUtf8(new Uint8Array([97, 98, 99])) // 'abc'
|
||||
*/
|
||||
export function bytesToUtf8(bytes) {
|
||||
return new TextDecoder().decode(bytes);
|
||||
}
|
||||
/**
|
||||
* Normalizes (non-hex) string or Uint8Array to Uint8Array.
|
||||
* Warning: when Uint8Array is passed, it would NOT get copied.
|
||||
* Keep in mind for future mutable operations.
|
||||
*/
|
||||
export function toBytes(data) {
|
||||
if (typeof data === 'string')
|
||||
data = utf8ToBytes(data);
|
||||
else if (isBytes(data))
|
||||
data = data.slice();
|
||||
else
|
||||
throw new Error(`Uint8Array expected, got ${typeof data}`);
|
||||
return data;
|
||||
}
|
||||
/**
|
||||
* Copies several Uint8Arrays into one.
|
||||
*/
|
||||
export function concatBytes(...arrays) {
|
||||
let sum = 0;
|
||||
for (let i = 0; i < arrays.length; i++) {
|
||||
const a = arrays[i];
|
||||
abytes(a);
|
||||
sum += a.length;
|
||||
}
|
||||
const res = new Uint8Array(sum);
|
||||
for (let i = 0, pad = 0; i < arrays.length; i++) {
|
||||
const a = arrays[i];
|
||||
res.set(a, pad);
|
||||
pad += a.length;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
export function checkOpts(defaults, opts) {
|
||||
if (opts == null || typeof opts !== 'object')
|
||||
throw new Error('options must be defined');
|
||||
const merged = Object.assign(defaults, opts);
|
||||
return merged;
|
||||
}
|
||||
// Compares 2 u8a-s in kinda constant time
|
||||
export function equalBytes(a, b) {
|
||||
if (a.length !== b.length)
|
||||
return false;
|
||||
let diff = 0;
|
||||
for (let i = 0; i < a.length; i++)
|
||||
diff |= a[i] ^ b[i];
|
||||
return diff === 0;
|
||||
}
|
||||
// For runtime check if class implements interface
|
||||
export class Hash {
|
||||
}
|
||||
/**
|
||||
* @__NO_SIDE_EFFECTS__
|
||||
*/
|
||||
export const wrapCipher = (params, c) => {
|
||||
Object.assign(c, params);
|
||||
return c;
|
||||
};
|
||||
// Polyfill for Safari 14
|
||||
export function setBigUint64(view, byteOffset, value, isLE) {
|
||||
if (typeof view.setBigUint64 === 'function')
|
||||
return view.setBigUint64(byteOffset, value, isLE);
|
||||
const _32n = BigInt(32);
|
||||
const _u32_max = BigInt(0xffffffff);
|
||||
const wh = Number((value >> _32n) & _u32_max);
|
||||
const wl = Number(value & _u32_max);
|
||||
const h = isLE ? 4 : 0;
|
||||
const l = isLE ? 0 : 4;
|
||||
view.setUint32(byteOffset + h, wh, isLE);
|
||||
view.setUint32(byteOffset + l, wl, isLE);
|
||||
}
|
||||
export function u64Lengths(ciphertext, AAD) {
|
||||
const num = new Uint8Array(16);
|
||||
const view = createView(num);
|
||||
setBigUint64(view, 0, BigInt(AAD ? AAD.length : 0), true);
|
||||
setBigUint64(view, 8, BigInt(ciphertext.length), true);
|
||||
return num;
|
||||
}
|
||||
//# sourceMappingURL=utils.js.map
|
||||
1
thrower_daemon/node_modules/@noble/ciphers/esm/utils.js.map
generated
vendored
Normal file
1
thrower_daemon/node_modules/@noble/ciphers/esm/utils.js.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
105
thrower_daemon/node_modules/@noble/ciphers/esm/webcrypto.js
generated
vendored
Normal file
105
thrower_daemon/node_modules/@noble/ciphers/esm/webcrypto.js
generated
vendored
Normal file
@@ -0,0 +1,105 @@
|
||||
// We use WebCrypto aka globalThis.crypto, which exists in browsers and node.js 16+.
|
||||
// node.js versions earlier than v19 don't declare it in global scope.
|
||||
// For node.js, package.js on#exports field mapping rewrites import
|
||||
// from `crypto` to `cryptoNode`, which imports native module.
|
||||
// Makes the utils un-importable in browsers without a bundler.
|
||||
// Once node.js 18 is deprecated, we can just drop the import.
|
||||
//
|
||||
// Use full path so that Node.js can rewrite it to `cryptoNode.js`.
|
||||
import { randomBytes, getWebcryptoSubtle } from '@noble/ciphers/crypto';
|
||||
import { concatBytes } from './utils.js';
|
||||
import { number, bytes as abytes } from './_assert.js';
|
||||
/**
|
||||
* Secure PRNG. Uses `crypto.getRandomValues`, which defers to OS.
|
||||
*/
|
||||
export { randomBytes, getWebcryptoSubtle };
|
||||
// Uses CSPRG for nonce, nonce injected in ciphertext
|
||||
export function managedNonce(fn) {
|
||||
number(fn.nonceLength);
|
||||
return ((key, ...args) => ({
|
||||
encrypt: (plaintext, ...argsEnc) => {
|
||||
const { nonceLength } = fn;
|
||||
const nonce = randomBytes(nonceLength);
|
||||
const ciphertext = fn(key, nonce, ...args).encrypt(plaintext, ...argsEnc);
|
||||
const out = concatBytes(nonce, ciphertext);
|
||||
ciphertext.fill(0);
|
||||
return out;
|
||||
},
|
||||
decrypt: (ciphertext, ...argsDec) => {
|
||||
const { nonceLength } = fn;
|
||||
const nonce = ciphertext.subarray(0, nonceLength);
|
||||
const data = ciphertext.subarray(nonceLength);
|
||||
return fn(key, nonce, ...args).decrypt(data, ...argsDec);
|
||||
},
|
||||
}));
|
||||
}
|
||||
// Overridable
|
||||
export const utils = {
|
||||
async encrypt(key, keyParams, cryptParams, plaintext) {
|
||||
const cr = getWebcryptoSubtle();
|
||||
const iKey = await cr.importKey('raw', key, keyParams, true, ['encrypt']);
|
||||
const ciphertext = await cr.encrypt(cryptParams, iKey, plaintext);
|
||||
return new Uint8Array(ciphertext);
|
||||
},
|
||||
async decrypt(key, keyParams, cryptParams, ciphertext) {
|
||||
const cr = getWebcryptoSubtle();
|
||||
const iKey = await cr.importKey('raw', key, keyParams, true, ['decrypt']);
|
||||
const plaintext = await cr.decrypt(cryptParams, iKey, ciphertext);
|
||||
return new Uint8Array(plaintext);
|
||||
},
|
||||
};
|
||||
const mode = {
|
||||
CBC: 'AES-CBC',
|
||||
CTR: 'AES-CTR',
|
||||
GCM: 'AES-GCM',
|
||||
};
|
||||
function getCryptParams(algo, nonce, AAD) {
|
||||
if (algo === mode.CBC)
|
||||
return { name: mode.CBC, iv: nonce };
|
||||
if (algo === mode.CTR)
|
||||
return { name: mode.CTR, counter: nonce, length: 64 };
|
||||
if (algo === mode.GCM) {
|
||||
if (AAD)
|
||||
return { name: mode.GCM, iv: nonce, additionalData: AAD };
|
||||
else
|
||||
return { name: mode.GCM, iv: nonce };
|
||||
}
|
||||
throw new Error('unknown aes block mode');
|
||||
}
|
||||
function generate(algo) {
|
||||
return (key, nonce, AAD) => {
|
||||
abytes(key);
|
||||
abytes(nonce);
|
||||
const keyParams = { name: algo, length: key.length * 8 };
|
||||
const cryptParams = getCryptParams(algo, nonce, AAD);
|
||||
return {
|
||||
// keyLength,
|
||||
encrypt(plaintext) {
|
||||
abytes(plaintext);
|
||||
return utils.encrypt(key, keyParams, cryptParams, plaintext);
|
||||
},
|
||||
decrypt(ciphertext) {
|
||||
abytes(ciphertext);
|
||||
return utils.decrypt(key, keyParams, cryptParams, ciphertext);
|
||||
},
|
||||
};
|
||||
};
|
||||
}
|
||||
export const cbc = generate(mode.CBC);
|
||||
export const ctr = generate(mode.CTR);
|
||||
export const gcm = generate(mode.GCM);
|
||||
// // Type tests
|
||||
// import { siv, gcm, ctr, ecb, cbc } from '../aes.js';
|
||||
// import { xsalsa20poly1305 } from '../salsa.js';
|
||||
// import { chacha20poly1305, xchacha20poly1305 } from '../chacha.js';
|
||||
// const wsiv = managedNonce(siv);
|
||||
// const wgcm = managedNonce(gcm);
|
||||
// const wctr = managedNonce(ctr);
|
||||
// const wcbc = managedNonce(cbc);
|
||||
// const wsalsapoly = managedNonce(xsalsa20poly1305);
|
||||
// const wchacha = managedNonce(chacha20poly1305);
|
||||
// const wxchacha = managedNonce(xchacha20poly1305);
|
||||
// // should fail
|
||||
// const wcbc2 = managedNonce(managedNonce(cbc));
|
||||
// const wecb = managedNonce(ecb);
|
||||
//# sourceMappingURL=webcrypto.js.map
|
||||
1
thrower_daemon/node_modules/@noble/ciphers/esm/webcrypto.js.map
generated
vendored
Normal file
1
thrower_daemon/node_modules/@noble/ciphers/esm/webcrypto.js.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"webcrypto.js","sourceRoot":"","sources":["../src/webcrypto.ts"],"names":[],"mappings":"AAAA,oFAAoF;AACpF,sEAAsE;AACtE,mEAAmE;AACnE,8DAA8D;AAC9D,+DAA+D;AAC/D,8DAA8D;AAC9D,EAAE;AACF,mEAAmE;AACnE,OAAO,EAAE,WAAW,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AACxE,OAAO,EAAuB,WAAW,EAAE,MAAM,YAAY,CAAC;AAC9D,OAAO,EAAE,MAAM,EAAE,KAAK,IAAI,MAAM,EAAE,MAAM,cAAc,CAAC;AAEvD;;GAEG;AACH,OAAO,EAAE,WAAW,EAAE,kBAAkB,EAAE,CAAC;AAe3C,qDAAqD;AACrD,MAAM,UAAU,YAAY,CAA4B,EAAK;IAC3D,MAAM,CAAC,EAAE,CAAC,WAAW,CAAC,CAAC;IACvB,OAAO,CAAC,CAAC,GAAe,EAAE,GAAG,IAAW,EAAO,EAAE,CAAC,CAAC;QACjD,OAAO,EAAE,CAAC,SAAqB,EAAE,GAAG,OAAc,EAAE,EAAE;YACpD,MAAM,EAAE,WAAW,EAAE,GAAG,EAAE,CAAC;YAC3B,MAAM,KAAK,GAAG,WAAW,CAAC,WAAW,CAAC,CAAC;YACvC,MAAM,UAAU,GAAI,EAAE,CAAC,GAAG,EAAE,KAAK,EAAE,GAAG,IAAI,CAAC,CAAC,OAAe,CAAC,SAAS,EAAE,GAAG,OAAO,CAAC,CAAC;YACnF,MAAM,GAAG,GAAG,WAAW,CAAC,KAAK,EAAE,UAAU,CAAC,CAAC;YAC3C,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YACnB,OAAO,GAAG,CAAC;QACb,CAAC;QACD,OAAO,EAAE,CAAC,UAAsB,EAAE,GAAG,OAAc,EAAE,EAAE;YACrD,MAAM,EAAE,WAAW,EAAE,GAAG,EAAE,CAAC;YAC3B,MAAM,KAAK,GAAG,UAAU,CAAC,QAAQ,CAAC,CAAC,EAAE,WAAW,CAAC,CAAC;YAClD,MAAM,IAAI,GAAG,UAAU,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC;YAC9C,OAAQ,EAAE,CAAC,GAAG,EAAE,KAAK,EAAE,GAAG,IAAI,CAAC,CAAC,OAAe,CAAC,IAAI,EAAE,GAAG,OAAO,CAAC,CAAC;QACpE,CAAC;KACF,CAAC,CAAmB,CAAC;AACxB,CAAC;AAED,cAAc;AACd,MAAM,CAAC,MAAM,KAAK,GAAG;IACnB,KAAK,CAAC,OAAO,CAAC,GAAe,EAAE,SAAc,EAAE,WAAgB,EAAE,SAAqB;QACpF,MAAM,EAAE,GAAG,kBAAkB,EAAE,CAAC;QAChC,MAAM,IAAI,GAAG,MAAM,EAAE,CAAC,SAAS,CAAC,KAAK,EAAE,GAAG,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC;QAC1E,MAAM,UAAU,GAAG,MAAM,EAAE,CAAC,OAAO,CAAC,WAAW,EAAE,IAAI,EAAE,SAAS,CAAC,CAAC;QAClE,OAAO,IAAI,UAAU,CAAC,UAAU,CAAC,CAAC;IACpC,CAAC;IACD,KAAK,CAAC,OAAO,CAAC,GAAe,EAAE,SAAc,EAAE,WAAgB,EAAE,UAAsB;QACrF,MAAM,EAAE,GAAG,kBAAkB,EAAE,CAAC;QAChC,MAAM,IAAI,GAAG,MAAM,EAAE,CAAC,SAAS,CAAC,KAAK,EAAE,GAAG,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC;QAC1E,MAAM,SAAS,GAAG,MAAM,EAAE,CAAC,OAAO,CAAC,WAAW,EAAE,IAAI,EAAE,UAAU,CAAC,CAAC;QAClE,OAAO,IAAI,UAAU,CAAC,SAAS,CAAC,CAAC;IACnC,CAAC;CACF,CAAC;AAEF,MAAM,IAAI,GAAG;IACX,GAAG,EAAE,SAAS;IACd,GAAG,EAAE,SAAS;IACd,GAAG,EAAE,SAAS;CACN,CAAC;AAGX,SAAS,cAAc,CAAC,IAAe,EAAE,KAAiB,EAAE,GAAgB;IAC1E,IAAI,IAAI,KAAK,IAAI,CAAC,GAAG;QAAE,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,GAAG,EAAE,EAAE,EAAE,KAAK,EAAE,CAAC;IAC5D,IAAI,IAAI,KAAK,IAAI,CAAC,GAAG;QAAE,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,GAAG,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC;IAC7E,IAAI,IAAI,KAAK,IAAI,CAAC,GAAG,EAAE,CAAC;QACtB,IAAI,GAAG;YAAE,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,GAAG,EAAE,EAAE,EAAE,KAAK,EAAE,cAAc,EAAE,GAAG,EAAE,CAAC;;YAC9D,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,GAAG,EAAE,EAAE,EAAE,KAAK,EAAE,CAAC;IAC5C,CAAC;IAED,MAAM,IAAI,KAAK,CAAC,wBAAwB,CAAC,CAAC;AAC5C,CAAC;AAED,SAAS,QAAQ,CAAC,IAAe;IAC/B,OAAO,CAAC,GAAe,EAAE,KAAiB,EAAE,GAAgB,EAAe,EAAE;QAC3E,MAAM,CAAC,GAAG,CAAC,CAAC;QACZ,MAAM,CAAC,KAAK,CAAC,CAAC;QACd,MAAM,SAAS,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACzD,MAAM,WAAW,GAAG,cAAc,CAAC,IAAI,EAAE,KAAK,EAAE,GAAG,CAAC,CAAC;QACrD,OAAO;YACL,aAAa;YACb,OAAO,CAAC,SAAqB;gBAC3B,MAAM,CAAC,SAAS,CAAC,CAAC;gBAClB,OAAO,KAAK,CAAC,OAAO,CAAC,GAAG,EAAE,SAAS,EAAE,WAAW,EAAE,SAAS,CAAC,CAAC;YAC/D,CAAC;YACD,OAAO,CAAC,UAAsB;gBAC5B,MAAM,CAAC,UAAU,CAAC,CAAC;gBACnB,OAAO,KAAK,CAAC,OAAO,CAAC,GAAG,EAAE,SAAS,EAAE,WAAW,EAAE,UAAU,CAAC,CAAC;YAChE,CAAC;SACF,CAAC;IACJ,CAAC,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,MAAM,GAAG,GAAG,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AACtC,MAAM,CAAC,MAAM,GAAG,GAAG,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AACtC,MAAM,CAAC,MAAM,GAAG,GAAG,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAEtC,gBAAgB;AAChB,uDAAuD;AACvD,kDAAkD;AAClD,sEAAsE;AAEtE,kCAAkC;AAClC,kCAAkC;AAClC,kCAAkC;AAClC,kCAAkC;AAClC,qDAAqD;AACrD,kDAAkD;AAClD,oDAAoD;AAEpD,iBAAiB;AACjB,iDAAiD;AACjD,kCAAkC"}
|
||||
7
thrower_daemon/node_modules/@noble/ciphers/ff1.d.ts
generated
vendored
Normal file
7
thrower_daemon/node_modules/@noble/ciphers/ff1.d.ts
generated
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
import { Cipher } from './utils.js';
|
||||
export declare function FF1(radix: number, key: Uint8Array, tweak?: Uint8Array): {
|
||||
encrypt(x: number[]): number[];
|
||||
decrypt(x: number[]): number[];
|
||||
};
|
||||
export declare function BinaryFF1(key: Uint8Array, tweak?: Uint8Array): Cipher;
|
||||
//# sourceMappingURL=ff1.d.ts.map
|
||||
1
thrower_daemon/node_modules/@noble/ciphers/ff1.d.ts.map
generated
vendored
Normal file
1
thrower_daemon/node_modules/@noble/ciphers/ff1.d.ts.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"ff1.d.ts","sourceRoot":"","sources":["src/ff1.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAoC,MAAM,YAAY,CAAC;AA0FtE,wBAAgB,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,UAAU,EAAE,KAAK,GAAE,UAAsB;eAGlE,MAAM,EAAE;eAUR,MAAM,EAAE;EAgBtB;AAqBD,wBAAgB,SAAS,CAAC,GAAG,EAAE,UAAU,EAAE,KAAK,GAAE,UAAsB,GAAG,MAAM,CAMhF"}
|
||||
154
thrower_daemon/node_modules/@noble/ciphers/ff1.js
generated
vendored
Normal file
154
thrower_daemon/node_modules/@noble/ciphers/ff1.js
generated
vendored
Normal file
@@ -0,0 +1,154 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.BinaryFF1 = exports.FF1 = void 0;
|
||||
const utils_js_1 = require("./utils.js");
|
||||
const aes_js_1 = require("./aes.js");
|
||||
// NOTE: no point in inlining encrypt instead of encryptBlock, since BigInt stuff will be slow
|
||||
const { expandKeyLE, encryptBlock } = aes_js_1.unsafe;
|
||||
// Format-preserving encryption algorithm (FPE-FF1) specified in NIST Special Publication 800-38G.
|
||||
// https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-38G.pdf
|
||||
const BLOCK_LEN = 16;
|
||||
function mod(a, b) {
|
||||
const result = a % b;
|
||||
return result >= 0 ? result : b + result;
|
||||
}
|
||||
function NUMradix(radix, data) {
|
||||
let res = BigInt(0);
|
||||
for (let i of data)
|
||||
res = res * BigInt(radix) + BigInt(i);
|
||||
return res;
|
||||
}
|
||||
function getRound(radix, key, tweak, x) {
|
||||
if (radix > 2 ** 16 - 1)
|
||||
throw new Error(`Invalid radix: ${radix}`);
|
||||
// radix**minlen ≥ 100
|
||||
const minLen = Math.ceil(Math.log(100) / Math.log(radix));
|
||||
const maxLen = 2 ** 32 - 1;
|
||||
// 2 ≤ minlen ≤ maxlen < 2**32
|
||||
if (2 > minLen || minLen > maxLen || maxLen >= 2 ** 32)
|
||||
throw new Error('Invalid radix: 2 ≤ minlen ≤ maxlen < 2**32');
|
||||
if (x.length < minLen || x.length > maxLen)
|
||||
throw new Error('X is outside minLen..maxLen bounds');
|
||||
const u = Math.floor(x.length / 2);
|
||||
const v = x.length - u;
|
||||
const b = Math.ceil(Math.ceil(v * Math.log2(radix)) / 8);
|
||||
const d = 4 * Math.ceil(b / 4) + 4;
|
||||
const padding = mod(-tweak.length - b - 1, 16);
|
||||
// P = [1]1 || [2]1 || [1]1 || [radix]3 || [10]1 || [u mod 256]1 || [n]4 || [t]4.
|
||||
const P = new Uint8Array([1, 2, 1, 0, 0, 0, 10, u, 0, 0, 0, 0, 0, 0, 0, 0]);
|
||||
const view = new DataView(P.buffer);
|
||||
view.setUint16(4, radix, false);
|
||||
view.setUint32(8, x.length, false);
|
||||
view.setUint32(12, tweak.length, false);
|
||||
// Q = T || [0](−t−b−1) mod 16 || [i]1 || [NUMradix(B)]b.
|
||||
const PQ = new Uint8Array(P.length + tweak.length + padding + 1 + b);
|
||||
PQ.set(P);
|
||||
P.fill(0);
|
||||
PQ.set(tweak, P.length);
|
||||
const xk = expandKeyLE(key);
|
||||
const round = (A, B, i, decrypt = false) => {
|
||||
// Q = ... || [i]1 || [NUMradix(B)]b.
|
||||
PQ[PQ.length - b - 1] = i;
|
||||
if (b)
|
||||
PQ.set((0, utils_js_1.numberToBytesBE)(NUMradix(radix, B), b), PQ.length - b);
|
||||
// PRF
|
||||
let r = new Uint8Array(16);
|
||||
for (let j = 0; j < PQ.length / BLOCK_LEN; j++) {
|
||||
for (let i = 0; i < BLOCK_LEN; i++)
|
||||
r[i] ^= PQ[j * BLOCK_LEN + i];
|
||||
encryptBlock(xk, r);
|
||||
}
|
||||
// Let S be the first d bytes of the following string of ⎡d/16⎤ blocks:
|
||||
// R || CIPHK(R ⊕[1]16) || CIPHK(R ⊕[2]16) ...CIPHK(R ⊕[⎡d / 16⎤ – 1]16).
|
||||
let s = Array.from(r);
|
||||
for (let j = 1; s.length < d; j++) {
|
||||
const block = (0, utils_js_1.numberToBytesBE)(BigInt(j), 16);
|
||||
for (let k = 0; k < BLOCK_LEN; k++)
|
||||
block[k] ^= r[k];
|
||||
s.push(...Array.from(encryptBlock(xk, block)));
|
||||
}
|
||||
let y = (0, utils_js_1.bytesToNumberBE)(Uint8Array.from(s.slice(0, d)));
|
||||
s.fill(0);
|
||||
if (decrypt)
|
||||
y = -y;
|
||||
const m = i % 2 === 0 ? u : v;
|
||||
let c = mod(NUMradix(radix, A) + y, BigInt(radix) ** BigInt(m));
|
||||
// STR(radix, m, c)
|
||||
const C = Array(m).fill(0);
|
||||
for (let i = 0; i < m; i++, c /= BigInt(radix))
|
||||
C[m - 1 - i] = Number(c % BigInt(radix));
|
||||
A.fill(0);
|
||||
A = B;
|
||||
B = C;
|
||||
return [A, B];
|
||||
};
|
||||
const destroy = () => {
|
||||
xk.fill(0);
|
||||
PQ.fill(0);
|
||||
};
|
||||
return { u, round, destroy };
|
||||
}
|
||||
const EMPTY_BUF = new Uint8Array([]);
|
||||
function FF1(radix, key, tweak = EMPTY_BUF) {
|
||||
const PQ = getRound.bind(null, radix, key, tweak);
|
||||
return {
|
||||
encrypt(x) {
|
||||
const { u, round, destroy } = PQ(x);
|
||||
let [A, B] = [x.slice(0, u), x.slice(u)];
|
||||
for (let i = 0; i < 10; i++)
|
||||
[A, B] = round(A, B, i);
|
||||
destroy();
|
||||
const res = A.concat(B);
|
||||
A.fill(0);
|
||||
B.fill(0);
|
||||
return res;
|
||||
},
|
||||
decrypt(x) {
|
||||
const { u, round, destroy } = PQ(x);
|
||||
// The FF1.Decrypt algorithm is similar to the FF1.Encrypt algorithm;
|
||||
// the differences are in Step 6, where:
|
||||
// 1) the order of the indices is reversed,
|
||||
// 2) the roles of A and B are swapped
|
||||
// 3) modular addition is replaced by modular subtraction, in Step 6vi.
|
||||
let [B, A] = [x.slice(0, u), x.slice(u)];
|
||||
for (let i = 9; i >= 0; i--)
|
||||
[A, B] = round(A, B, i, true);
|
||||
destroy();
|
||||
const res = B.concat(A);
|
||||
A.fill(0);
|
||||
B.fill(0);
|
||||
return res;
|
||||
},
|
||||
};
|
||||
}
|
||||
exports.FF1 = FF1;
|
||||
// Binary string which encodes each byte in little-endian byte order
|
||||
const binLE = {
|
||||
encode(bytes) {
|
||||
const x = [];
|
||||
for (let i = 0; i < bytes.length; i++) {
|
||||
for (let j = 0, tmp = bytes[i]; j < 8; j++, tmp >>= 1)
|
||||
x.push(tmp & 1);
|
||||
}
|
||||
return x;
|
||||
},
|
||||
decode(b) {
|
||||
if (b.length % 8)
|
||||
throw new Error('Invalid binary string');
|
||||
const res = new Uint8Array(b.length / 8);
|
||||
for (let i = 0, j = 0; i < res.length; i++) {
|
||||
res[i] = b[j++] | (b[j++] << 1) | (b[j++] << 2) | (b[j++] << 3);
|
||||
res[i] |= (b[j++] << 4) | (b[j++] << 5) | (b[j++] << 6) | (b[j++] << 7);
|
||||
}
|
||||
return res;
|
||||
},
|
||||
};
|
||||
function BinaryFF1(key, tweak = EMPTY_BUF) {
|
||||
const ff1 = FF1(2, key, tweak);
|
||||
return {
|
||||
encrypt: (x) => binLE.decode(ff1.encrypt(binLE.encode(x))),
|
||||
decrypt: (x) => binLE.decode(ff1.decrypt(binLE.encode(x))),
|
||||
};
|
||||
}
|
||||
exports.BinaryFF1 = BinaryFF1;
|
||||
//# sourceMappingURL=ff1.js.map
|
||||
1
thrower_daemon/node_modules/@noble/ciphers/ff1.js.map
generated
vendored
Normal file
1
thrower_daemon/node_modules/@noble/ciphers/ff1.js.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
1
thrower_daemon/node_modules/@noble/ciphers/index.d.ts
generated
vendored
Normal file
1
thrower_daemon/node_modules/@noble/ciphers/index.d.ts
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
//# sourceMappingURL=index.d.ts.map
|
||||
1
thrower_daemon/node_modules/@noble/ciphers/index.d.ts.map
generated
vendored
Normal file
1
thrower_daemon/node_modules/@noble/ciphers/index.d.ts.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["src/index.ts"],"names":[],"mappings":""}
|
||||
3
thrower_daemon/node_modules/@noble/ciphers/index.js
generated
vendored
Normal file
3
thrower_daemon/node_modules/@noble/ciphers/index.js
generated
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
"use strict";
|
||||
throw new Error('noble-ciphers have no entry-point: consult README for usage');
|
||||
//# sourceMappingURL=index.js.map
|
||||
1
thrower_daemon/node_modules/@noble/ciphers/index.js.map
generated
vendored
Normal file
1
thrower_daemon/node_modules/@noble/ciphers/index.js.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"index.js","sourceRoot":"","sources":["src/index.ts"],"names":[],"mappings":";AAAA,MAAM,IAAI,KAAK,CAAC,6DAA6D,CAAC,CAAC"}
|
||||
126
thrower_daemon/node_modules/@noble/ciphers/package.json
generated
vendored
Normal file
126
thrower_daemon/node_modules/@noble/ciphers/package.json
generated
vendored
Normal file
@@ -0,0 +1,126 @@
|
||||
{
|
||||
"name": "@noble/ciphers",
|
||||
"version": "0.5.3",
|
||||
"description": "Auditable & minimal JS implementation of Salsa20, ChaCha and AES",
|
||||
"files": ["esm", "src", "*.js", "*.js.map", "*.d.ts", "*.d.ts.map"],
|
||||
"scripts": {
|
||||
"bench": "node benchmark/aead.js noble && node benchmark/ciphers.js noble",
|
||||
"bench:all": "node benchmark/{aead,ciphers,poly}.js",
|
||||
"bench:install": "cd benchmark && npm install && cd ../../",
|
||||
"build": "npm run build:clean; tsc && tsc -p tsconfig.esm.json",
|
||||
"build:release": "cd build && npm i && npm run build",
|
||||
"build:clean": "rm *.{js,d.ts,js.map,d.ts.map} esm/*.{js,d.ts,js.map,d.ts.map} 2> /dev/null",
|
||||
"lint": "prettier --check 'src/**/*.{js,ts}' 'test/**/*.{js,ts,mjs}'",
|
||||
"format": "prettier --write 'src/**/*.{js,ts}' 'test/**/*.{js,ts,mjs}'",
|
||||
"test": "node test/index.js"
|
||||
},
|
||||
"author": "Paul Miller (https://paulmillr.com)",
|
||||
"homepage": "https://paulmillr.com/noble/",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/paulmillr/noble-ciphers.git"
|
||||
},
|
||||
"license": "MIT",
|
||||
"sideEffects": false,
|
||||
"devDependencies": {
|
||||
"@paulmillr/jsbt": "0.1.0",
|
||||
"@scure/base": "1.1.3",
|
||||
"fast-check": "3.0.0",
|
||||
"micro-bmark": "0.3.1",
|
||||
"micro-should": "0.4.0",
|
||||
"prettier": "3.1.1",
|
||||
"typescript": "5.3.2"
|
||||
},
|
||||
"main": "index.js",
|
||||
"exports": {
|
||||
".": {
|
||||
"types": "./index.d.ts",
|
||||
"import": "./esm/index.js",
|
||||
"default": "./index.js"
|
||||
},
|
||||
"./_micro": {
|
||||
"types": "./_micro.d.ts",
|
||||
"import": "./esm/_micro.js",
|
||||
"default": "./_micro.js"
|
||||
},
|
||||
"./_poly1305": {
|
||||
"types": "./_poly1305.d.ts",
|
||||
"import": "./esm/_poly1305.js",
|
||||
"default": "./_poly1305.js"
|
||||
},
|
||||
"./_polyval": {
|
||||
"types": "./_polyval.d.ts",
|
||||
"import": "./esm/_polyval.js",
|
||||
"default": "./_polyval.js"
|
||||
},
|
||||
"./crypto": {
|
||||
"types": "./crypto.d.ts",
|
||||
"node": {
|
||||
"import": "./esm/cryptoNode.js",
|
||||
"default": "./cryptoNode.js"
|
||||
},
|
||||
"import": "./esm/crypto.js",
|
||||
"default": "./crypto.js"
|
||||
},
|
||||
"./aes": {
|
||||
"types": "./aes.d.ts",
|
||||
"import": "./esm/aes.js",
|
||||
"default": "./aes.js"
|
||||
},
|
||||
"./chacha": {
|
||||
"types": "./chacha.d.ts",
|
||||
"import": "./esm/chacha.js",
|
||||
"default": "./chacha.js"
|
||||
},
|
||||
"./salsa": {
|
||||
"types": "./salsa.d.ts",
|
||||
"import": "./esm/salsa.js",
|
||||
"default": "./salsa.js"
|
||||
},
|
||||
"./ff1": {
|
||||
"types": "./ff1.d.ts",
|
||||
"import": "./esm/ff1.js",
|
||||
"default": "./ff1.js"
|
||||
},
|
||||
"./utils": {
|
||||
"types": "./utils.d.ts",
|
||||
"import": "./esm/utils.js",
|
||||
"default": "./utils.js"
|
||||
},
|
||||
"./index": {
|
||||
"types": "./index.d.ts",
|
||||
"import": "./esm/index.js",
|
||||
"default": "./index.js"
|
||||
},
|
||||
"./webcrypto": {
|
||||
"types": "./webcrypto.d.ts",
|
||||
"import": "./esm/webcrypto.js",
|
||||
"default": "./webcrypto.js"
|
||||
}
|
||||
},
|
||||
"browser": {
|
||||
"node:crypto": false,
|
||||
"./crypto": "./crypto.js"
|
||||
},
|
||||
"keywords": [
|
||||
"salsa20",
|
||||
"chacha",
|
||||
"aes",
|
||||
"cryptography",
|
||||
"crypto",
|
||||
"noble",
|
||||
"cipher",
|
||||
"ciphers",
|
||||
"xsalsa20",
|
||||
"xchacha20",
|
||||
"poly1305",
|
||||
"xsalsa20poly1305",
|
||||
"chacha20poly1305",
|
||||
"xchacha20poly1305",
|
||||
"secretbox",
|
||||
"rijndael",
|
||||
"siv",
|
||||
"ff1"
|
||||
],
|
||||
"funding": "https://paulmillr.com/funding/"
|
||||
}
|
||||
36
thrower_daemon/node_modules/@noble/ciphers/salsa.d.ts
generated
vendored
Normal file
36
thrower_daemon/node_modules/@noble/ciphers/salsa.d.ts
generated
vendored
Normal file
@@ -0,0 +1,36 @@
|
||||
import { Cipher } from './utils.js';
|
||||
/**
|
||||
* hsalsa hashing function, used primarily in xsalsa, to hash
|
||||
* key and nonce into key' and nonce'.
|
||||
* Same as salsaCore, but there doesn't seem to be a way to move the block
|
||||
* out without 25% performance hit.
|
||||
*/
|
||||
export declare function hsalsa(s: Uint32Array, k: Uint32Array, i: Uint32Array, o32: Uint32Array): void;
|
||||
/**
|
||||
* Salsa20 from original paper.
|
||||
* With 12-byte nonce, it's not safe to use fill it with random (CSPRNG), due to collision chance.
|
||||
*/
|
||||
export declare const salsa20: import("./utils.js").XorStream;
|
||||
/**
|
||||
* xsalsa20 eXtended-nonce salsa.
|
||||
* With 24-byte nonce, it's safe to use fill it with random (CSPRNG).
|
||||
*/
|
||||
export declare const xsalsa20: import("./utils.js").XorStream;
|
||||
/**
|
||||
* xsalsa20-poly1305 eXtended-nonce salsa.
|
||||
* With 24-byte nonce, it's safe to use fill it with random (CSPRNG).
|
||||
* Also known as secretbox from libsodium / nacl.
|
||||
*/
|
||||
export declare const xsalsa20poly1305: ((key: Uint8Array, nonce: Uint8Array) => Cipher) & {
|
||||
blockSize: number;
|
||||
nonceLength: number;
|
||||
tagLength: number;
|
||||
};
|
||||
/**
|
||||
* Alias to xsalsa20poly1305, for compatibility with libsodium / nacl
|
||||
*/
|
||||
export declare function secretbox(key: Uint8Array, nonce: Uint8Array): {
|
||||
seal: (plaintext: Uint8Array) => Uint8Array;
|
||||
open: (ciphertext: Uint8Array) => Uint8Array;
|
||||
};
|
||||
//# sourceMappingURL=salsa.d.ts.map
|
||||
1
thrower_daemon/node_modules/@noble/ciphers/salsa.d.ts.map
generated
vendored
Normal file
1
thrower_daemon/node_modules/@noble/ciphers/salsa.d.ts.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"salsa.d.ts","sourceRoot":"","sources":["src/salsa.ts"],"names":[],"mappings":"AAGA,OAAO,EAAc,MAAM,EAAc,MAAM,YAAY,CAAC;AAsD5D;;;;;GAKG;AAEH,wBAAgB,MAAM,CACpB,CAAC,EAAE,WAAW,EAAE,CAAC,EAAE,WAAW,EAAE,CAAC,EAAE,WAAW,EAAE,GAAG,EAAE,WAAW,QA6BjE;AAED;;;GAGG;AACH,eAAO,MAAM,OAAO,gCAGlB,CAAC;AAEH;;;GAGG;AACH,eAAO,MAAM,QAAQ,gCAGnB,CAAC;AAEH;;;;GAIG;AACH,eAAO,MAAM,gBAAgB,SAErB,UAAU,SAAS,UAAU,KAAG,MAAM;;;;CAgD7C,CAAC;AAEF;;GAEG;AACH,wBAAgB,SAAS,CAAC,GAAG,EAAE,UAAU,EAAE,KAAK,EAAE,UAAU;;;EAG3D"}
|
||||
210
thrower_daemon/node_modules/@noble/ciphers/salsa.js
generated
vendored
Normal file
210
thrower_daemon/node_modules/@noble/ciphers/salsa.js
generated
vendored
Normal file
@@ -0,0 +1,210 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.secretbox = exports.xsalsa20poly1305 = exports.xsalsa20 = exports.salsa20 = exports.hsalsa = void 0;
|
||||
const _assert_js_1 = require("./_assert.js");
|
||||
const _arx_js_1 = require("./_arx.js");
|
||||
const _poly1305_js_1 = require("./_poly1305.js");
|
||||
const utils_js_1 = require("./utils.js");
|
||||
// Salsa20 stream cipher was released in 2005.
|
||||
// Salsa's goal was to implement AES replacement that does not rely on S-Boxes,
|
||||
// which are hard to implement in a constant-time manner.
|
||||
// https://cr.yp.to/snuffle.html, https://cr.yp.to/snuffle/salsafamily-20071225.pdf
|
||||
/**
|
||||
* Salsa20 core function.
|
||||
*/
|
||||
// prettier-ignore
|
||||
function salsaCore(s, k, n, out, cnt, rounds = 20) {
|
||||
// Based on https://cr.yp.to/salsa20.html
|
||||
let y00 = s[0], y01 = k[0], y02 = k[1], y03 = k[2], // "expa" Key Key Key
|
||||
y04 = k[3], y05 = s[1], y06 = n[0], y07 = n[1], // Key "nd 3" Nonce Nonce
|
||||
y08 = cnt, y09 = 0, y10 = s[2], y11 = k[4], // Pos. Pos. "2-by" Key
|
||||
y12 = k[5], y13 = k[6], y14 = k[7], y15 = s[3]; // Key Key Key "te k"
|
||||
// Save state to temporary variables
|
||||
let x00 = y00, x01 = y01, x02 = y02, x03 = y03, x04 = y04, x05 = y05, x06 = y06, x07 = y07, x08 = y08, x09 = y09, x10 = y10, x11 = y11, x12 = y12, x13 = y13, x14 = y14, x15 = y15;
|
||||
for (let r = 0; r < rounds; r += 2) {
|
||||
x04 ^= (0, _arx_js_1.rotl)(x00 + x12 | 0, 7);
|
||||
x08 ^= (0, _arx_js_1.rotl)(x04 + x00 | 0, 9);
|
||||
x12 ^= (0, _arx_js_1.rotl)(x08 + x04 | 0, 13);
|
||||
x00 ^= (0, _arx_js_1.rotl)(x12 + x08 | 0, 18);
|
||||
x09 ^= (0, _arx_js_1.rotl)(x05 + x01 | 0, 7);
|
||||
x13 ^= (0, _arx_js_1.rotl)(x09 + x05 | 0, 9);
|
||||
x01 ^= (0, _arx_js_1.rotl)(x13 + x09 | 0, 13);
|
||||
x05 ^= (0, _arx_js_1.rotl)(x01 + x13 | 0, 18);
|
||||
x14 ^= (0, _arx_js_1.rotl)(x10 + x06 | 0, 7);
|
||||
x02 ^= (0, _arx_js_1.rotl)(x14 + x10 | 0, 9);
|
||||
x06 ^= (0, _arx_js_1.rotl)(x02 + x14 | 0, 13);
|
||||
x10 ^= (0, _arx_js_1.rotl)(x06 + x02 | 0, 18);
|
||||
x03 ^= (0, _arx_js_1.rotl)(x15 + x11 | 0, 7);
|
||||
x07 ^= (0, _arx_js_1.rotl)(x03 + x15 | 0, 9);
|
||||
x11 ^= (0, _arx_js_1.rotl)(x07 + x03 | 0, 13);
|
||||
x15 ^= (0, _arx_js_1.rotl)(x11 + x07 | 0, 18);
|
||||
x01 ^= (0, _arx_js_1.rotl)(x00 + x03 | 0, 7);
|
||||
x02 ^= (0, _arx_js_1.rotl)(x01 + x00 | 0, 9);
|
||||
x03 ^= (0, _arx_js_1.rotl)(x02 + x01 | 0, 13);
|
||||
x00 ^= (0, _arx_js_1.rotl)(x03 + x02 | 0, 18);
|
||||
x06 ^= (0, _arx_js_1.rotl)(x05 + x04 | 0, 7);
|
||||
x07 ^= (0, _arx_js_1.rotl)(x06 + x05 | 0, 9);
|
||||
x04 ^= (0, _arx_js_1.rotl)(x07 + x06 | 0, 13);
|
||||
x05 ^= (0, _arx_js_1.rotl)(x04 + x07 | 0, 18);
|
||||
x11 ^= (0, _arx_js_1.rotl)(x10 + x09 | 0, 7);
|
||||
x08 ^= (0, _arx_js_1.rotl)(x11 + x10 | 0, 9);
|
||||
x09 ^= (0, _arx_js_1.rotl)(x08 + x11 | 0, 13);
|
||||
x10 ^= (0, _arx_js_1.rotl)(x09 + x08 | 0, 18);
|
||||
x12 ^= (0, _arx_js_1.rotl)(x15 + x14 | 0, 7);
|
||||
x13 ^= (0, _arx_js_1.rotl)(x12 + x15 | 0, 9);
|
||||
x14 ^= (0, _arx_js_1.rotl)(x13 + x12 | 0, 13);
|
||||
x15 ^= (0, _arx_js_1.rotl)(x14 + x13 | 0, 18);
|
||||
}
|
||||
// Write output
|
||||
let oi = 0;
|
||||
out[oi++] = (y00 + x00) | 0;
|
||||
out[oi++] = (y01 + x01) | 0;
|
||||
out[oi++] = (y02 + x02) | 0;
|
||||
out[oi++] = (y03 + x03) | 0;
|
||||
out[oi++] = (y04 + x04) | 0;
|
||||
out[oi++] = (y05 + x05) | 0;
|
||||
out[oi++] = (y06 + x06) | 0;
|
||||
out[oi++] = (y07 + x07) | 0;
|
||||
out[oi++] = (y08 + x08) | 0;
|
||||
out[oi++] = (y09 + x09) | 0;
|
||||
out[oi++] = (y10 + x10) | 0;
|
||||
out[oi++] = (y11 + x11) | 0;
|
||||
out[oi++] = (y12 + x12) | 0;
|
||||
out[oi++] = (y13 + x13) | 0;
|
||||
out[oi++] = (y14 + x14) | 0;
|
||||
out[oi++] = (y15 + x15) | 0;
|
||||
}
|
||||
/**
|
||||
* hsalsa hashing function, used primarily in xsalsa, to hash
|
||||
* key and nonce into key' and nonce'.
|
||||
* Same as salsaCore, but there doesn't seem to be a way to move the block
|
||||
* out without 25% performance hit.
|
||||
*/
|
||||
// prettier-ignore
|
||||
function hsalsa(s, k, i, o32) {
|
||||
let x00 = s[0], x01 = k[0], x02 = k[1], x03 = k[2], x04 = k[3], x05 = s[1], x06 = i[0], x07 = i[1], x08 = i[2], x09 = i[3], x10 = s[2], x11 = k[4], x12 = k[5], x13 = k[6], x14 = k[7], x15 = s[3];
|
||||
for (let r = 0; r < 20; r += 2) {
|
||||
x04 ^= (0, _arx_js_1.rotl)(x00 + x12 | 0, 7);
|
||||
x08 ^= (0, _arx_js_1.rotl)(x04 + x00 | 0, 9);
|
||||
x12 ^= (0, _arx_js_1.rotl)(x08 + x04 | 0, 13);
|
||||
x00 ^= (0, _arx_js_1.rotl)(x12 + x08 | 0, 18);
|
||||
x09 ^= (0, _arx_js_1.rotl)(x05 + x01 | 0, 7);
|
||||
x13 ^= (0, _arx_js_1.rotl)(x09 + x05 | 0, 9);
|
||||
x01 ^= (0, _arx_js_1.rotl)(x13 + x09 | 0, 13);
|
||||
x05 ^= (0, _arx_js_1.rotl)(x01 + x13 | 0, 18);
|
||||
x14 ^= (0, _arx_js_1.rotl)(x10 + x06 | 0, 7);
|
||||
x02 ^= (0, _arx_js_1.rotl)(x14 + x10 | 0, 9);
|
||||
x06 ^= (0, _arx_js_1.rotl)(x02 + x14 | 0, 13);
|
||||
x10 ^= (0, _arx_js_1.rotl)(x06 + x02 | 0, 18);
|
||||
x03 ^= (0, _arx_js_1.rotl)(x15 + x11 | 0, 7);
|
||||
x07 ^= (0, _arx_js_1.rotl)(x03 + x15 | 0, 9);
|
||||
x11 ^= (0, _arx_js_1.rotl)(x07 + x03 | 0, 13);
|
||||
x15 ^= (0, _arx_js_1.rotl)(x11 + x07 | 0, 18);
|
||||
x01 ^= (0, _arx_js_1.rotl)(x00 + x03 | 0, 7);
|
||||
x02 ^= (0, _arx_js_1.rotl)(x01 + x00 | 0, 9);
|
||||
x03 ^= (0, _arx_js_1.rotl)(x02 + x01 | 0, 13);
|
||||
x00 ^= (0, _arx_js_1.rotl)(x03 + x02 | 0, 18);
|
||||
x06 ^= (0, _arx_js_1.rotl)(x05 + x04 | 0, 7);
|
||||
x07 ^= (0, _arx_js_1.rotl)(x06 + x05 | 0, 9);
|
||||
x04 ^= (0, _arx_js_1.rotl)(x07 + x06 | 0, 13);
|
||||
x05 ^= (0, _arx_js_1.rotl)(x04 + x07 | 0, 18);
|
||||
x11 ^= (0, _arx_js_1.rotl)(x10 + x09 | 0, 7);
|
||||
x08 ^= (0, _arx_js_1.rotl)(x11 + x10 | 0, 9);
|
||||
x09 ^= (0, _arx_js_1.rotl)(x08 + x11 | 0, 13);
|
||||
x10 ^= (0, _arx_js_1.rotl)(x09 + x08 | 0, 18);
|
||||
x12 ^= (0, _arx_js_1.rotl)(x15 + x14 | 0, 7);
|
||||
x13 ^= (0, _arx_js_1.rotl)(x12 + x15 | 0, 9);
|
||||
x14 ^= (0, _arx_js_1.rotl)(x13 + x12 | 0, 13);
|
||||
x15 ^= (0, _arx_js_1.rotl)(x14 + x13 | 0, 18);
|
||||
}
|
||||
let oi = 0;
|
||||
o32[oi++] = x00;
|
||||
o32[oi++] = x05;
|
||||
o32[oi++] = x10;
|
||||
o32[oi++] = x15;
|
||||
o32[oi++] = x06;
|
||||
o32[oi++] = x07;
|
||||
o32[oi++] = x08;
|
||||
o32[oi++] = x09;
|
||||
}
|
||||
exports.hsalsa = hsalsa;
|
||||
/**
|
||||
* Salsa20 from original paper.
|
||||
* With 12-byte nonce, it's not safe to use fill it with random (CSPRNG), due to collision chance.
|
||||
*/
|
||||
exports.salsa20 = (0, _arx_js_1.createCipher)(salsaCore, {
|
||||
allowShortKeys: true,
|
||||
counterRight: true,
|
||||
});
|
||||
/**
|
||||
* xsalsa20 eXtended-nonce salsa.
|
||||
* With 24-byte nonce, it's safe to use fill it with random (CSPRNG).
|
||||
*/
|
||||
exports.xsalsa20 = (0, _arx_js_1.createCipher)(salsaCore, {
|
||||
counterRight: true,
|
||||
extendNonceFn: hsalsa,
|
||||
});
|
||||
/**
|
||||
* xsalsa20-poly1305 eXtended-nonce salsa.
|
||||
* With 24-byte nonce, it's safe to use fill it with random (CSPRNG).
|
||||
* Also known as secretbox from libsodium / nacl.
|
||||
*/
|
||||
exports.xsalsa20poly1305 = (0, utils_js_1.wrapCipher)({ blockSize: 64, nonceLength: 24, tagLength: 16 }, (key, nonce) => {
|
||||
const tagLength = 16;
|
||||
(0, _assert_js_1.bytes)(key, 32);
|
||||
(0, _assert_js_1.bytes)(nonce, 24);
|
||||
return {
|
||||
encrypt: (plaintext, output) => {
|
||||
(0, _assert_js_1.bytes)(plaintext);
|
||||
// This is small optimization (calculate auth key with same call as encryption itself) makes it hard
|
||||
// to separate tag calculation and encryption itself, since 32 byte is half-block of salsa (64 byte)
|
||||
const clength = plaintext.length + 32;
|
||||
if (output) {
|
||||
(0, _assert_js_1.bytes)(output, clength);
|
||||
}
|
||||
else {
|
||||
output = new Uint8Array(clength);
|
||||
}
|
||||
output.set(plaintext, 32);
|
||||
(0, exports.xsalsa20)(key, nonce, output, output);
|
||||
const authKey = output.subarray(0, 32);
|
||||
const tag = (0, _poly1305_js_1.poly1305)(output.subarray(32), authKey);
|
||||
// Clean auth key, even though JS provides no guarantees about memory cleaning
|
||||
output.set(tag, tagLength);
|
||||
output.subarray(0, tagLength).fill(0);
|
||||
return output.subarray(tagLength);
|
||||
},
|
||||
decrypt: (ciphertext) => {
|
||||
(0, _assert_js_1.bytes)(ciphertext);
|
||||
const clength = ciphertext.length;
|
||||
if (clength < tagLength)
|
||||
throw new Error('encrypted data should be at least 16 bytes');
|
||||
// Create new ciphertext array:
|
||||
// auth tag auth tag from ciphertext ciphertext
|
||||
// [bytes 0..16] [bytes 16..32] [bytes 32..]
|
||||
// 16 instead of 32, because we already have 16 byte tag
|
||||
const ciphertext_ = new Uint8Array(clength + tagLength); // alloc
|
||||
ciphertext_.set(ciphertext, tagLength);
|
||||
// Each xsalsa20 calls to hsalsa to calculate key, but seems not much perf difference
|
||||
// Separate call to calculate authkey, since first bytes contains tag
|
||||
const authKey = (0, exports.xsalsa20)(key, nonce, new Uint8Array(32)); // alloc(32)
|
||||
const tag = (0, _poly1305_js_1.poly1305)(ciphertext_.subarray(32), authKey);
|
||||
if (!(0, utils_js_1.equalBytes)(ciphertext_.subarray(16, 32), tag))
|
||||
throw new Error('invalid tag');
|
||||
const plaintext = (0, exports.xsalsa20)(key, nonce, ciphertext_); // alloc
|
||||
// Clean auth key, even though JS provides no guarantees about memory cleaning
|
||||
plaintext.subarray(0, 32).fill(0);
|
||||
authKey.fill(0);
|
||||
return plaintext.subarray(32);
|
||||
},
|
||||
};
|
||||
});
|
||||
/**
|
||||
* Alias to xsalsa20poly1305, for compatibility with libsodium / nacl
|
||||
*/
|
||||
function secretbox(key, nonce) {
|
||||
const xs = (0, exports.xsalsa20poly1305)(key, nonce);
|
||||
return { seal: xs.encrypt, open: xs.decrypt };
|
||||
}
|
||||
exports.secretbox = secretbox;
|
||||
//# sourceMappingURL=salsa.js.map
|
||||
1
thrower_daemon/node_modules/@noble/ciphers/salsa.js.map
generated
vendored
Normal file
1
thrower_daemon/node_modules/@noble/ciphers/salsa.js.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
217
thrower_daemon/node_modules/@noble/ciphers/src/_arx.ts
generated
vendored
Normal file
217
thrower_daemon/node_modules/@noble/ciphers/src/_arx.ts
generated
vendored
Normal file
@@ -0,0 +1,217 @@
|
||||
// Basic utils for ARX (add-rotate-xor) salsa and chacha ciphers.
|
||||
import { number as anumber, bytes as abytes, bool as abool } from './_assert.js';
|
||||
import { XorStream, checkOpts, u32 } from './utils.js';
|
||||
|
||||
/*
|
||||
RFC8439 requires multi-step cipher stream, where
|
||||
authKey starts with counter: 0, actual msg with counter: 1.
|
||||
|
||||
For this, we need a way to re-use nonce / counter:
|
||||
|
||||
const counter = new Uint8Array(4);
|
||||
chacha(..., counter, ...); // counter is now 1
|
||||
chacha(..., counter, ...); // counter is now 2
|
||||
|
||||
This is complicated:
|
||||
|
||||
- 32-bit counters are enough, no need for 64-bit: max ArrayBuffer size in JS is 4GB
|
||||
- Original papers don't allow mutating counters
|
||||
- Counter overflow is undefined [^1]
|
||||
- Idea A: allow providing (nonce | counter) instead of just nonce, re-use it
|
||||
- Caveat: Cannot be re-used through all cases:
|
||||
- * chacha has (counter | nonce)
|
||||
- * xchacha has (nonce16 | counter | nonce16)
|
||||
- Idea B: separate nonce / counter and provide separate API for counter re-use
|
||||
- Caveat: there are different counter sizes depending on an algorithm.
|
||||
- salsa & chacha also differ in structures of key & sigma:
|
||||
salsa20: s[0] | k(4) | s[1] | nonce(2) | ctr(2) | s[2] | k(4) | s[3]
|
||||
chacha: s(4) | k(8) | ctr(1) | nonce(3)
|
||||
chacha20orig: s(4) | k(8) | ctr(2) | nonce(2)
|
||||
- Idea C: helper method such as `setSalsaState(key, nonce, sigma, data)`
|
||||
- Caveat: we can't re-use counter array
|
||||
|
||||
xchacha [^2] uses the subkey and remaining 8 byte nonce with ChaCha20 as normal
|
||||
(prefixed by 4 NUL bytes, since [RFC8439] specifies a 12-byte nonce).
|
||||
|
||||
[^1]: https://mailarchive.ietf.org/arch/msg/cfrg/gsOnTJzcbgG6OqD8Sc0GO5aR_tU/
|
||||
[^2]: https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-xchacha#appendix-A.2
|
||||
*/
|
||||
|
||||
// We can't make top-level var depend on utils.utf8ToBytes
|
||||
// because it's not present in all envs. Creating a similar fn here
|
||||
const _utf8ToBytes = (str: string) => Uint8Array.from(str.split('').map((c) => c.charCodeAt(0)));
|
||||
const sigma16 = _utf8ToBytes('expand 16-byte k');
|
||||
const sigma32 = _utf8ToBytes('expand 32-byte k');
|
||||
const sigma16_32 = u32(sigma16);
|
||||
const sigma32_32 = u32(sigma32);
|
||||
export const sigma = sigma32_32.slice();
|
||||
|
||||
export function rotl(a: number, b: number): number {
|
||||
return (a << b) | (a >>> (32 - b));
|
||||
}
|
||||
|
||||
export type CipherCoreFn = (
|
||||
sigma: Uint32Array,
|
||||
key: Uint32Array,
|
||||
nonce: Uint32Array,
|
||||
output: Uint32Array,
|
||||
counter: number,
|
||||
rounds?: number
|
||||
) => void;
|
||||
|
||||
export type ExtendNonceFn = (
|
||||
sigma: Uint32Array,
|
||||
key: Uint32Array,
|
||||
input: Uint32Array,
|
||||
output: Uint32Array
|
||||
) => void;
|
||||
|
||||
export type CipherOpts = {
|
||||
allowShortKeys?: boolean; // Original salsa / chacha allow 16-byte keys
|
||||
extendNonceFn?: ExtendNonceFn;
|
||||
counterLength?: number;
|
||||
counterRight?: boolean; // right: nonce|counter; left: counter|nonce
|
||||
rounds?: number;
|
||||
};
|
||||
|
||||
// Is byte array aligned to 4 byte offset (u32)?
|
||||
function isAligned32(b: Uint8Array) {
|
||||
return b.byteOffset % 4 === 0;
|
||||
}
|
||||
|
||||
// Salsa and Chacha block length is always 512-bit
|
||||
const BLOCK_LEN = 64;
|
||||
const BLOCK_LEN32 = 16;
|
||||
|
||||
// new Uint32Array([2**32]) // => Uint32Array(1) [ 0 ]
|
||||
// new Uint32Array([2**32-1]) // => Uint32Array(1) [ 4294967295 ]
|
||||
const MAX_COUNTER = 2 ** 32 - 1;
|
||||
|
||||
const U32_EMPTY = new Uint32Array();
|
||||
function runCipher(
|
||||
core: CipherCoreFn,
|
||||
sigma: Uint32Array,
|
||||
key: Uint32Array,
|
||||
nonce: Uint32Array,
|
||||
data: Uint8Array,
|
||||
output: Uint8Array,
|
||||
counter: number,
|
||||
rounds: number
|
||||
): void {
|
||||
const len = data.length;
|
||||
const block = new Uint8Array(BLOCK_LEN);
|
||||
const b32 = u32(block);
|
||||
// Make sure that buffers aligned to 4 bytes
|
||||
const isAligned = isAligned32(data) && isAligned32(output);
|
||||
const d32 = isAligned ? u32(data) : U32_EMPTY;
|
||||
const o32 = isAligned ? u32(output) : U32_EMPTY;
|
||||
for (let pos = 0; pos < len; counter++) {
|
||||
core(sigma, key, nonce, b32, counter, rounds);
|
||||
if (counter >= MAX_COUNTER) throw new Error('arx: counter overflow');
|
||||
const take = Math.min(BLOCK_LEN, len - pos);
|
||||
// aligned to 4 bytes
|
||||
if (isAligned && take === BLOCK_LEN) {
|
||||
const pos32 = pos / 4;
|
||||
if (pos % 4 !== 0) throw new Error('arx: invalid block position');
|
||||
for (let j = 0, posj: number; j < BLOCK_LEN32; j++) {
|
||||
posj = pos32 + j;
|
||||
o32[posj] = d32[posj] ^ b32[j];
|
||||
}
|
||||
pos += BLOCK_LEN;
|
||||
continue;
|
||||
}
|
||||
for (let j = 0, posj; j < take; j++) {
|
||||
posj = pos + j;
|
||||
output[posj] = data[posj] ^ block[j];
|
||||
}
|
||||
pos += take;
|
||||
}
|
||||
}
|
||||
|
||||
export function createCipher(core: CipherCoreFn, opts: CipherOpts): XorStream {
|
||||
const { allowShortKeys, extendNonceFn, counterLength, counterRight, rounds } = checkOpts(
|
||||
{ allowShortKeys: false, counterLength: 8, counterRight: false, rounds: 20 },
|
||||
opts
|
||||
);
|
||||
if (typeof core !== 'function') throw new Error('core must be a function');
|
||||
anumber(counterLength);
|
||||
anumber(rounds);
|
||||
abool(counterRight);
|
||||
abool(allowShortKeys);
|
||||
return (
|
||||
key: Uint8Array,
|
||||
nonce: Uint8Array,
|
||||
data: Uint8Array,
|
||||
output?: Uint8Array,
|
||||
counter = 0
|
||||
): Uint8Array => {
|
||||
abytes(key);
|
||||
abytes(nonce);
|
||||
abytes(data);
|
||||
const len = data.length;
|
||||
if (!output) output = new Uint8Array(len);
|
||||
abytes(output);
|
||||
anumber(counter);
|
||||
if (counter < 0 || counter >= MAX_COUNTER) throw new Error('arx: counter overflow');
|
||||
if (output.length < len)
|
||||
throw new Error(`arx: output (${output.length}) is shorter than data (${len})`);
|
||||
const toClean = [];
|
||||
|
||||
// Key & sigma
|
||||
// key=16 -> sigma16, k=key|key
|
||||
// key=32 -> sigma32, k=key
|
||||
let l = key.length,
|
||||
k: Uint8Array,
|
||||
sigma: Uint32Array;
|
||||
if (l === 32) {
|
||||
k = key.slice();
|
||||
toClean.push(k);
|
||||
sigma = sigma32_32;
|
||||
} else if (l === 16 && allowShortKeys) {
|
||||
k = new Uint8Array(32);
|
||||
k.set(key);
|
||||
k.set(key, 16);
|
||||
sigma = sigma16_32;
|
||||
toClean.push(k);
|
||||
} else {
|
||||
throw new Error(`arx: invalid 32-byte key, got length=${l}`);
|
||||
}
|
||||
|
||||
// Nonce
|
||||
// salsa20: 8 (8-byte counter)
|
||||
// chacha20orig: 8 (8-byte counter)
|
||||
// chacha20: 12 (4-byte counter)
|
||||
// xsalsa20: 24 (16 -> hsalsa, 8 -> old nonce)
|
||||
// xchacha20: 24 (16 -> hchacha, 8 -> old nonce)
|
||||
// Align nonce to 4 bytes
|
||||
if (!isAligned32(nonce)) {
|
||||
nonce = nonce.slice();
|
||||
toClean.push(nonce);
|
||||
}
|
||||
|
||||
const k32 = u32(k);
|
||||
// hsalsa & hchacha: handle extended nonce
|
||||
if (extendNonceFn) {
|
||||
if (nonce.length !== 24) throw new Error(`arx: extended nonce must be 24 bytes`);
|
||||
extendNonceFn(sigma, k32, u32(nonce.subarray(0, 16)), k32);
|
||||
nonce = nonce.subarray(16);
|
||||
}
|
||||
|
||||
// Handle nonce counter
|
||||
const nonceNcLen = 16 - counterLength;
|
||||
if (nonceNcLen !== nonce.length)
|
||||
throw new Error(`arx: nonce must be ${nonceNcLen} or 16 bytes`);
|
||||
|
||||
// Pad counter when nonce is 64 bit
|
||||
if (nonceNcLen !== 12) {
|
||||
const nc = new Uint8Array(12);
|
||||
nc.set(nonce, counterRight ? 0 : 12 - nonce.length);
|
||||
nonce = nc;
|
||||
toClean.push(nonce);
|
||||
}
|
||||
const n32 = u32(nonce);
|
||||
runCipher(core, sigma, k32, n32, data, output, counter, rounds);
|
||||
while (toClean.length > 0) toClean.pop()!.fill(0);
|
||||
return output;
|
||||
};
|
||||
}
|
||||
50
thrower_daemon/node_modules/@noble/ciphers/src/_assert.ts
generated
vendored
Normal file
50
thrower_daemon/node_modules/@noble/ciphers/src/_assert.ts
generated
vendored
Normal file
@@ -0,0 +1,50 @@
|
||||
function number(n: number) {
|
||||
if (!Number.isSafeInteger(n) || n < 0) throw new Error(`positive integer expected, not ${n}`);
|
||||
}
|
||||
|
||||
function bool(b: boolean) {
|
||||
if (typeof b !== 'boolean') throw new Error(`boolean expected, not ${b}`);
|
||||
}
|
||||
|
||||
export function isBytes(a: unknown): a is Uint8Array {
|
||||
return (
|
||||
a instanceof Uint8Array ||
|
||||
(a != null && typeof a === 'object' && a.constructor.name === 'Uint8Array')
|
||||
);
|
||||
}
|
||||
|
||||
function bytes(b: Uint8Array | undefined, ...lengths: number[]) {
|
||||
if (!isBytes(b)) throw new Error('Uint8Array expected');
|
||||
if (lengths.length > 0 && !lengths.includes(b.length))
|
||||
throw new Error(`Uint8Array expected of length ${lengths}, not of length=${b.length}`);
|
||||
}
|
||||
|
||||
export type Hash = {
|
||||
(data: Uint8Array): Uint8Array;
|
||||
blockLen: number;
|
||||
outputLen: number;
|
||||
create: any;
|
||||
};
|
||||
function hash(hash: Hash) {
|
||||
if (typeof hash !== 'function' || typeof hash.create !== 'function')
|
||||
throw new Error('hash must be wrapped by utils.wrapConstructor');
|
||||
number(hash.outputLen);
|
||||
number(hash.blockLen);
|
||||
}
|
||||
|
||||
function exists(instance: any, checkFinished = true) {
|
||||
if (instance.destroyed) throw new Error('Hash instance has been destroyed');
|
||||
if (checkFinished && instance.finished) throw new Error('Hash#digest() has already been called');
|
||||
}
|
||||
|
||||
function output(out: any, instance: any) {
|
||||
bytes(out);
|
||||
const min = instance.outputLen;
|
||||
if (out.length < min) {
|
||||
throw new Error(`digestInto() expects output buffer of length at least ${min}`);
|
||||
}
|
||||
}
|
||||
|
||||
export { number, bool, bytes, hash, exists, output };
|
||||
const assert = { number, bool, bytes, hash, exists, output };
|
||||
export default assert;
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user