Preload libsodium.so

This commit is contained in:
Vishnu Mohandas 2021-05-30 03:28:33 +05:30
parent c1e1a99163
commit 065d400ef2
138 changed files with 7977 additions and 1 deletions

View file

@ -55,7 +55,8 @@ dependencies:
flutter_secure_storage: ^4.2.0
uni_links: ^0.5.1
crisp: ^0.1.3
flutter_sodium: ^0.2.0
flutter_sodium:
path: thirdparty/flutter_sodium
pedantic: ^1.9.2
page_transition: "^1.1.7+2"
scrollable_positioned_list: ^0.1.10

12
thirdparty/flutter_sodium/.gitignore vendored Normal file
View file

@ -0,0 +1,12 @@
.DS_Store
.atom/
.idea
.dart_tool/
.packages
.pub/
.vscode/
build/
**/ios/.generated/
**/ios/Flutter/.last_build_id
packages
pubspec.lock

10
thirdparty/flutter_sodium/.metadata vendored Normal file
View file

@ -0,0 +1,10 @@
# This file tracks properties of this Flutter project.
# Used by Flutter tool to assess capabilities and perform upgrades etc.
#
# This file should be version controlled and should not be manually edited.
version:
revision: f139b11009aeb8ed2a3a3aa8b0066e482709dde3
channel: stable
project_type: plugin

View file

@ -0,0 +1,5 @@
## Acknowledgements
The flutter_sodium plugin uses code from the following libraries:
- [libsodium](https://github.com/jedisct1/libsodium), ISC license

52
thirdparty/flutter_sodium/CHANGELOG.md vendored Normal file
View file

@ -0,0 +1,52 @@
## 0.2.0 - March 12, 2021
* migrates to ffi 1.0.0
* stable null safety
## 0.2.0-nullsafety.1 - February 5, 2021
* adds support for sodium_core_hchacha and hsalsa (merge 0.1.11)
## 0.2.0-nullsafety.0 - February 5, 2021
* implements null safety
## 0.1.11 - February 5, 2021
* adds support for loading libsodium on Linux and Windows
* adds support for sodium_core_hchacha and hsalsa
## 0.1.10 - December 11, 2020
* adds support for sodium_runtime_*, sodium_memcmp, sodium_pad and sodium_unpad
## 0.1.9 - October 31, 2020
* sets Android build.gradle minSdkVersion 16, fixing implicit permissions READ_PHONE_STATE, READ_EXTERNAL_STORAGE and WRITE_EXTERNAL_STORAGE
## 0.1.8 - October 2, 2020
* backwards incompatible Sodium.cryptoPwhashStr* changes, str return value and parameter type changed from ascii decoded String to null terminated Uint8List
## 0.1.7 - September 30, 2020
* improves API documentation
* removes obsolete convert package dependency
* fixes Android deprecated API build warning
## 0.1.6 - September 30, 2020
* fixes "cannot find symbol" compile error on Android
## 0.1.5 - September 30, 2020
* fixes symbol lookup issue since flutter 1.20
* fixes platforms key in pubspec.yaml
## 0.1.4 - September 16, 2020
* adds sodium hex and base64 conversion helpers
* removes sodium prefix from version and init functions (breaks API)
* fixes generic_hash crash on Android
## 0.1.3 - July 17, 2020
* reverts invalid multi-platform pubspec settings
## 0.1.2 - July 16, 2020
* fixes documentation and multi-platform support warnings
## 0.1.1 - July 15, 2020
* fixes "Failed to lookup symbol" errors on iOS in release mode.
## 0.1.0 - June 10, 2020
* rewrite flutter_sodium using FFI

27
thirdparty/flutter_sodium/LICENSE vendored Normal file
View file

@ -0,0 +1,27 @@
// Copyright 2020 First Floor Software. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of First Floor Software nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

88
thirdparty/flutter_sodium/README.md vendored Normal file
View file

@ -0,0 +1,88 @@
# flutter_sodium
With flutter_sodium you get access to the modern, easy-to-use [libsodium](https://download.libsodium.org/doc/) crypto library in your [Flutter](https://flutter.io) apps. One set of crypto APIs supporting both Android and iOS.
[![Pub](https://img.shields.io/pub/v/flutter_sodium.svg)](https://pub.dartlang.org/packages/flutter_sodium)
## Getting Started
In your flutter project add the dependency:
```yml
dependencies:
...
flutter_sodium: ^0.2.0
```
Import the plugin and initialize it. Sodium.init() initializes the plugin and should be called before any other function provided by flutter_sodium.
```dart
import 'package:flutter_sodium/flutter_sodium.dart';
// initialize sodium
Sodium.init();
```
## Usage example
```dart
// Password hashing (using Argon)
final password = 'my password';
final str = PasswordHash.hashStringStorage(password);
print(str);
// verify hash str
final valid = PasswordHash.verifyStorage(str, password);
assert(valid);
```
This project includes an extensive example app with runnable code samples. Be sure to check it out!
<img src="https://raw.githubusercontent.com/firstfloorsoftware/flutter_sodium/master/example/assets/screenshots/screenshot1.png" width="300">
## API coverage
The flutter_sodium plugin implements the following libsodium APIs:
- crypto_aead
- crypto_auth
- crypto_box
- crypto_generichash
- crypto_hash
- crypto_kdf
- crypto_kx
- crypto_onetimeauth
- crypto_pwhash
- crypto_scalarmult
- crypto_secretbox
- crypto_secretstream
- crypto_shorthash
- crypto_sign
- crypto_stream
- randombytes
- sodium_version
API coverage is not 100% complete, track the progress in [issue #61](https://github.com/firstfloorsoftware/flutter_sodium/issues/61)
## Dart APIs
The plugin includes a core API that maps native libsodium functions 1:1 to Dart equivalents. The core API is available in the class [`Sodium`](https://github.com/firstfloorsoftware/flutter_sodium/blob/master/lib/flutter_sodium.dart). Dart naming conventions are used for core API function names. A native libsodium function such as `crypto_pwhash_str`, is available in flutter as `Sodium.cryptoPwhashStr`.
Also included in flutter_sodium is a high-level, opinionated API providing access to libsodium in a Dart friendly manner. The various functions are available in separate Dart classes. Password hashing for example is available in the `PasswordHash` class. The high-level API depends on the core API to get things done.
## Migrating to fluttter_sodium FFI
The FFI implementation of flutter_sodium is backwards incompatible with the previous platform channel implementation. The list of changes:
- the entire FFI API is now synchronous, while the previous implementation was entirely asynchronous
- all hardcoded libsodium constants are now available as properties on the Sodium class.
- in the platform channel versions the Android and iOS implementations were not in sync. Some functions were available only in iOS, others only in Android. With the FFI implementation, there is a single API covering both platforms.
## Background threads
Since the entire FFI API is synchronous, you'll need to do some extra work to execute long running crypto function on a background thread. Luckily this is very easy with Flutter's [compute function](https://api.flutter.dev/flutter/foundation/compute.html).
The following code snippet demonstrates running a password hash on the background thread.
```dart
final pw = 'hello world';
final str = await compute(PasswordHash.hashStringStorageModerate, pw);
print(str);
```

View file

@ -0,0 +1,8 @@
*.iml
.gradle
/local.properties
/.idea/workspace.xml
/.idea/libraries
.DS_Store
/build
/captures

View file

@ -0,0 +1,10 @@
apply plugin: 'com.android.library'
android {
compileSdkVersion 28
defaultConfig {
minSdkVersion 16
}
}
dependencies {
}

View file

@ -0,0 +1,4 @@
org.gradle.jvmargs=-Xmx1536M
android.enableR8=true
android.useAndroidX=true
android.enableJetifier=true

View file

@ -0,0 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.2-all.zip

View file

@ -0,0 +1 @@
rootProject.name = 'flutter_sodium'

View file

@ -0,0 +1,3 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.firstfloorsoftware.flutter_sodium">
</manifest>

View file

@ -0,0 +1,59 @@
package com.firstfloorsoftware.flutter_sodium;
import androidx.annotation.NonNull;
import io.flutter.embedding.engine.plugins.FlutterPlugin;
import io.flutter.plugin.common.MethodCall;
import io.flutter.plugin.common.MethodChannel;
import io.flutter.plugin.common.MethodChannel.MethodCallHandler;
import io.flutter.plugin.common.MethodChannel.Result;
import io.flutter.plugin.common.PluginRegistry.Registrar;
/** FlutterSodiumPlugin */
public class FlutterSodiumPlugin implements FlutterPlugin, MethodCallHandler {
private static boolean hasLoadedLibrary = false;
/// The MethodChannel that will the communication between Flutter and native Android
///
/// This local reference serves to register the plugin with the Flutter Engine and unregister it
/// when the Flutter Engine is detached from the Activity
private MethodChannel channel;
@Override
public void onAttachedToEngine(@NonNull FlutterPluginBinding flutterPluginBinding) {
channel = new MethodChannel(flutterPluginBinding.getBinaryMessenger(), "sodium");
channel.setMethodCallHandler(this);
if (hasLoadedLibrary) {
return;
}
System.loadLibrary("libsodium.so");
hasLoadedLibrary = true;
}
// This static function is optional and equivalent to onAttachedToEngine. It supports the old
// pre-Flutter-1.12 Android projects. You are encouraged to continue supporting
// plugin registration via this function while apps migrate to use the new Android APIs
// post-flutter-1.12 via https://flutter.dev/go/android-project-migration.
//
// It is encouraged to share logic between onAttachedToEngine and registerWith to keep
// them functionally equivalent. Only one of onAttachedToEngine or registerWith will be called
// depending on the user's project. onAttachedToEngine or registerWith must both be defined
// in the same class.
public static void registerWith(Registrar registrar) {
final MethodChannel channel = new MethodChannel(registrar.messenger(), "sodium");
channel.setMethodCallHandler(new FlutterSodiumPlugin());
}
@Override
public void onMethodCall(@NonNull MethodCall call, @NonNull Result result) {
if (call.method.equals("getPlatformVersion")) {
result.success("Android " + android.os.Build.VERSION.RELEASE);
} else {
result.notImplemented();
}
}
@Override
public void onDetachedFromEngine(@NonNull FlutterPluginBinding binding) {
channel.setMethodCallHandler(null);
}
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

View file

@ -0,0 +1,37 @@
# Miscellaneous
*.class
*.log
*.pyc
*.swp
.DS_Store
.atom/
.buildlog/
.history
.svn/
# IntelliJ related
*.iml
*.ipr
*.iws
.idea/
# The .vscode folder contains launch configuration and tasks you configure in
# VS Code which you may wish to be included in version control, so this line
# is commented out by default.
#.vscode/
# Flutter/Dart/Pub related
**/doc/api/
.dart_tool/
.flutter-plugins
.flutter-plugins-dependencies
.packages
.pub-cache/
.pub/
/build/
# Web related
lib/generated_plugin_registrant.dart
# Exceptions to above rules.
!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages

View file

@ -0,0 +1,10 @@
# This file tracks properties of this Flutter project.
# Used by Flutter tool to assess capabilities and perform upgrades etc.
#
# This file should be version controlled and should not be manually edited.
version:
revision: f139b11009aeb8ed2a3a3aa8b0066e482709dde3
channel: stable
project_type: app

View file

@ -0,0 +1,3 @@
# flutter_sodium_example
Demonstrates how to use the flutter_sodium plugin.

View file

@ -0,0 +1,7 @@
gradle-wrapper.jar
/.gradle
/captures/
/gradlew
/gradlew.bat
/local.properties
GeneratedPluginRegistrant.java

View file

@ -0,0 +1,67 @@
def localProperties = new Properties()
def localPropertiesFile = rootProject.file('local.properties')
if (localPropertiesFile.exists()) {
localPropertiesFile.withReader('UTF-8') { reader ->
localProperties.load(reader)
}
}
def flutterRoot = localProperties.getProperty('flutter.sdk')
if (flutterRoot == null) {
throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.")
}
def flutterVersionCode = localProperties.getProperty('flutter.versionCode')
if (flutterVersionCode == null) {
flutterVersionCode = '1'
}
def flutterVersionName = localProperties.getProperty('flutter.versionName')
if (flutterVersionName == null) {
flutterVersionName = '1.0'
}
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
android {
compileSdkVersion 28
sourceSets {
main.java.srcDirs += 'src/main/kotlin'
}
lintOptions {
disable 'InvalidPackage'
}
defaultConfig {
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
applicationId "com.firstfloorsoftware.flutter_sodium_example"
minSdkVersion 16
targetSdkVersion 28
versionCode flutterVersionCode.toInteger()
versionName flutterVersionName
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
// TODO: Add your own signing config for the release build.
// Signing with the debug keys for now, so `flutter run --release` works.
signingConfig signingConfigs.debug
}
}
}
flutter {
source '../..'
}
dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test:runner:1.1.1'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1'
}

View file

@ -0,0 +1,7 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.firstfloorsoftware.flutter_sodium_example">
<!-- Flutter needs it to communicate with the running application
to allow setting breakpoints, to provide hot reload, etc.
-->
<uses-permission android:name="android.permission.INTERNET"/>
</manifest>

View file

@ -0,0 +1,30 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.firstfloorsoftware.flutter_sodium_example">
<!-- io.flutter.app.FlutterApplication is an android.app.Application that
calls FlutterMain.startInitialization(this); in its onCreate method.
In most cases you can leave this as-is, but you if you want to provide
additional functionality it is fine to subclass or reimplement
FlutterApplication and put your custom class here. -->
<application
android:name="io.flutter.app.FlutterApplication"
android:label="flutter_sodium_example"
android:icon="@mipmap/ic_launcher">
<activity
android:name=".MainActivity"
android:launchMode="singleTop"
android:theme="@style/LaunchTheme"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
android:hardwareAccelerated="true"
android:windowSoftInputMode="adjustResize">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<!-- Don't delete the meta-data below.
This is used by the Flutter tool to generate GeneratedPluginRegistrant.java -->
<meta-data
android:name="flutterEmbedding"
android:value="2" />
</application>
</manifest>

View file

@ -0,0 +1,12 @@
package com.firstfloorsoftware.flutter_sodium_example
import androidx.annotation.NonNull;
import io.flutter.embedding.android.FlutterActivity
import io.flutter.embedding.engine.FlutterEngine
import io.flutter.plugins.GeneratedPluginRegistrant
class MainActivity: FlutterActivity() {
override fun configureFlutterEngine(@NonNull flutterEngine: FlutterEngine) {
GeneratedPluginRegistrant.registerWith(flutterEngine);
}
}

View file

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Modify this file to customize your launch splash screen -->
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@android:color/white" />
<!-- You can insert your own image assets here -->
<!-- <item>
<bitmap
android:gravity="center"
android:src="@mipmap/launch_image" />
</item> -->
</layer-list>

Binary file not shown.

After

Width:  |  Height:  |  Size: 544 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 442 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 721 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

View file

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="LaunchTheme" parent="@android:style/Theme.Black.NoTitleBar">
<!-- Show a splash screen on the activity. Automatically removed when
Flutter draws its first frame -->
<item name="android:windowBackground">@drawable/launch_background</item>
</style>
</resources>

View file

@ -0,0 +1,7 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.firstfloorsoftware.flutter_sodium_example">
<!-- Flutter needs it to communicate with the running application
to allow setting breakpoints, to provide hot reload, etc.
-->
<uses-permission android:name="android.permission.INTERNET"/>
</manifest>

View file

@ -0,0 +1,31 @@
buildscript {
ext.kotlin_version = '1.3.50'
repositories {
google()
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.5.0'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}
allprojects {
repositories {
google()
jcenter()
}
}
rootProject.buildDir = '../build'
subprojects {
project.buildDir = "${rootProject.buildDir}/${project.name}"
}
subprojects {
project.evaluationDependsOn(':app')
}
task clean(type: Delete) {
delete rootProject.buildDir
}

View file

@ -0,0 +1,4 @@
org.gradle.jvmargs=-Xmx1536M
android.enableR8=true
android.useAndroidX=true
android.enableJetifier=true

View file

@ -0,0 +1,6 @@
#Fri Jun 23 08:50:38 CEST 2017
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.2-all.zip

View file

@ -0,0 +1,15 @@
include ':app'
def flutterProjectRoot = rootProject.projectDir.parentFile.toPath()
def plugins = new Properties()
def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins')
if (pluginsFile.exists()) {
pluginsFile.withReader('UTF-8') { reader -> plugins.load(reader) }
}
plugins.each { name, path ->
def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile()
include ":$name"
project(":$name").projectDir = pluginDirectory
}

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 314 KiB

View file

@ -0,0 +1,17 @@
```dart
import 'package:flutter_sodium/flutter_sodium.dart';
// initialize sodium (one-time)
Sodium.init();
// Password hashing (using Argon)
final password = 'my password';
final str = PasswordHash.hashStringStorage(password);
print(str);
// verify hash str
final valid = PasswordHash.verifyStorage(str, password);
assert(valid);
```

View file

@ -0,0 +1,32 @@
*.mode1v3
*.mode2v3
*.moved-aside
*.pbxuser
*.perspectivev3
**/*sync/
.sconsign.dblite
.tags*
**/.vagrant/
**/DerivedData/
Icon?
**/Pods/
**/.symlinks/
profile
xcuserdata
**/.generated/
Flutter/App.framework
Flutter/Flutter.framework
Flutter/Flutter.podspec
Flutter/Generated.xcconfig
Flutter/app.flx
Flutter/app.zip
Flutter/flutter_assets/
Flutter/flutter_export_environment.sh
ServiceDefinitions.json
Runner/GeneratedPluginRegistrant.*
# Exceptions to above rules.
!default.mode1v3
!default.mode2v3
!default.pbxuser
!default.perspectivev3

View file

@ -0,0 +1,26 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>$(DEVELOPMENT_LANGUAGE)</string>
<key>CFBundleExecutable</key>
<string>App</string>
<key>CFBundleIdentifier</key>
<string>io.flutter.flutter.app</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>App</string>
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>1.0</string>
<key>MinimumOSVersion</key>
<string>8.0</string>
</dict>
</plist>

View file

@ -0,0 +1,3 @@
#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"
#include "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"
#include "Generated.xcconfig"

View file

@ -0,0 +1,3 @@
#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"
#include "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"
#include "Generated.xcconfig"

View file

@ -0,0 +1,41 @@
# Uncomment this line to define a global platform for your project
# platform :ios, '9.0'
# CocoaPods analytics sends network stats synchronously affecting flutter build latency.
ENV['COCOAPODS_DISABLE_STATS'] = 'true'
project 'Runner', {
'Debug' => :debug,
'Profile' => :release,
'Release' => :release,
}
def flutter_root
generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__)
unless File.exist?(generated_xcode_build_settings_path)
raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first"
end
File.foreach(generated_xcode_build_settings_path) do |line|
matches = line.match(/FLUTTER_ROOT\=(.*)/)
return matches[1].strip if matches
end
raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get"
end
require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root)
flutter_ios_podfile_setup
target 'Runner' do
use_frameworks!
use_modular_headers!
flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__))
end
post_install do |installer|
installer.pods_project.targets.each do |target|
flutter_additional_ios_build_settings(target)
end
end

View file

@ -0,0 +1,28 @@
PODS:
- Flutter (1.0.0)
- flutter_sodium (0.0.1):
- Flutter
- url_launcher (0.0.1):
- Flutter
DEPENDENCIES:
- Flutter (from `Flutter`)
- flutter_sodium (from `.symlinks/plugins/flutter_sodium/ios`)
- url_launcher (from `.symlinks/plugins/url_launcher/ios`)
EXTERNAL SOURCES:
Flutter:
:path: Flutter
flutter_sodium:
:path: ".symlinks/plugins/flutter_sodium/ios"
url_launcher:
:path: ".symlinks/plugins/url_launcher/ios"
SPEC CHECKSUMS:
Flutter: 434fef37c0980e73bb6479ef766c45957d4b510c
flutter_sodium: c84426b4de738514b5b66cfdeb8a06634e72fe0b
url_launcher: 6fef411d543ceb26efce54b05a0a40bfd74cbbef
PODFILE CHECKSUM: aafe91acc616949ddb318b77800a7f51bffa2a4c
COCOAPODS: 1.10.1

View file

@ -0,0 +1,574 @@
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 46;
objects = {
/* Begin PBXBuildFile section */
1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; };
149FB357672EE250597AC929 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C838EC254A0CCC58ACAA81B /* Pods_Runner.framework */; };
3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; };
74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; };
97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; };
97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; };
97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; };
/* End PBXBuildFile section */
/* Begin PBXCopyFilesBuildPhase section */
9705A1C41CF9048500538489 /* Embed Frameworks */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647;
dstPath = "";
dstSubfolderSpec = 10;
files = (
);
name = "Embed Frameworks";
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */
1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = "<group>"; };
1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = "<group>"; };
3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = "<group>"; };
4C838EC254A0CCC58ACAA81B /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; };
74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = "<group>"; };
74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = "<group>"; };
80F2A67D88D5308C7C03107D /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = "<group>"; };
8675E4787B222EA609FB9914 /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = "<group>"; };
9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = "<group>"; };
9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = "<group>"; };
97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; };
97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; };
97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
E4CB2F8B43CC8EB2CA464EDF /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
97C146EB1CF9000F007C117D /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
149FB357672EE250597AC929 /* Pods_Runner.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
15C5CDE098F27C804253D648 /* Pods */ = {
isa = PBXGroup;
children = (
8675E4787B222EA609FB9914 /* Pods-Runner.debug.xcconfig */,
E4CB2F8B43CC8EB2CA464EDF /* Pods-Runner.release.xcconfig */,
80F2A67D88D5308C7C03107D /* Pods-Runner.profile.xcconfig */,
);
name = Pods;
path = Pods;
sourceTree = "<group>";
};
6B28B36E418160D8E8452581 /* Frameworks */ = {
isa = PBXGroup;
children = (
4C838EC254A0CCC58ACAA81B /* Pods_Runner.framework */,
);
name = Frameworks;
sourceTree = "<group>";
};
9740EEB11CF90186004384FC /* Flutter */ = {
isa = PBXGroup;
children = (
3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */,
9740EEB21CF90195004384FC /* Debug.xcconfig */,
7AFA3C8E1D35360C0083082E /* Release.xcconfig */,
9740EEB31CF90195004384FC /* Generated.xcconfig */,
);
name = Flutter;
sourceTree = "<group>";
};
97C146E51CF9000F007C117D = {
isa = PBXGroup;
children = (
9740EEB11CF90186004384FC /* Flutter */,
97C146F01CF9000F007C117D /* Runner */,
97C146EF1CF9000F007C117D /* Products */,
15C5CDE098F27C804253D648 /* Pods */,
6B28B36E418160D8E8452581 /* Frameworks */,
);
sourceTree = "<group>";
};
97C146EF1CF9000F007C117D /* Products */ = {
isa = PBXGroup;
children = (
97C146EE1CF9000F007C117D /* Runner.app */,
);
name = Products;
sourceTree = "<group>";
};
97C146F01CF9000F007C117D /* Runner */ = {
isa = PBXGroup;
children = (
97C146FA1CF9000F007C117D /* Main.storyboard */,
97C146FD1CF9000F007C117D /* Assets.xcassets */,
97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */,
97C147021CF9000F007C117D /* Info.plist */,
97C146F11CF9000F007C117D /* Supporting Files */,
1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */,
1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */,
74858FAE1ED2DC5600515810 /* AppDelegate.swift */,
74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */,
);
path = Runner;
sourceTree = "<group>";
};
97C146F11CF9000F007C117D /* Supporting Files */ = {
isa = PBXGroup;
children = (
);
name = "Supporting Files";
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
97C146ED1CF9000F007C117D /* Runner */ = {
isa = PBXNativeTarget;
buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */;
buildPhases = (
E29DD6FFE92E2C786601B5A9 /* [CP] Check Pods Manifest.lock */,
9740EEB61CF901F6004384FC /* Run Script */,
97C146EA1CF9000F007C117D /* Sources */,
97C146EB1CF9000F007C117D /* Frameworks */,
97C146EC1CF9000F007C117D /* Resources */,
9705A1C41CF9048500538489 /* Embed Frameworks */,
3B06AD1E1E4923F5004D2608 /* Thin Binary */,
52D823E0B64BC1FAD8E1E7C2 /* [CP] Embed Pods Frameworks */,
);
buildRules = (
);
dependencies = (
);
name = Runner;
productName = Runner;
productReference = 97C146EE1CF9000F007C117D /* Runner.app */;
productType = "com.apple.product-type.application";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
97C146E61CF9000F007C117D /* Project object */ = {
isa = PBXProject;
attributes = {
LastUpgradeCheck = 1020;
ORGANIZATIONNAME = "The Chromium Authors";
TargetAttributes = {
97C146ED1CF9000F007C117D = {
CreatedOnToolsVersion = 7.3.1;
LastSwiftMigration = 1100;
};
};
};
buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */;
compatibilityVersion = "Xcode 3.2";
developmentRegion = en;
hasScannedForEncodings = 0;
knownRegions = (
en,
Base,
);
mainGroup = 97C146E51CF9000F007C117D;
productRefGroup = 97C146EF1CF9000F007C117D /* Products */;
projectDirPath = "";
projectRoot = "";
targets = (
97C146ED1CF9000F007C117D /* Runner */,
);
};
/* End PBXProject section */
/* Begin PBXResourcesBuildPhase section */
97C146EC1CF9000F007C117D /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */,
3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */,
97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */,
97C146FC1CF9000F007C117D /* Main.storyboard in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXShellScriptBuildPhase section */
3B06AD1E1E4923F5004D2608 /* Thin Binary */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
name = "Thin Binary";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin";
};
52D823E0B64BC1FAD8E1E7C2 /* [CP] Embed Pods Frameworks */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh",
"${BUILT_PRODUCTS_DIR}/flutter_sodium/flutter_sodium.framework",
"${BUILT_PRODUCTS_DIR}/url_launcher/url_launcher.framework",
);
name = "[CP] Embed Pods Frameworks";
outputPaths = (
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/flutter_sodium.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/url_launcher.framework",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n";
showEnvVarsInLog = 0;
};
9740EEB61CF901F6004384FC /* Run Script */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
name = "Run Script";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build";
};
E29DD6FFE92E2C786601B5A9 /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
);
inputPaths = (
"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
"${PODS_ROOT}/Manifest.lock",
);
name = "[CP] Check Pods Manifest.lock";
outputFileListPaths = (
);
outputPaths = (
"$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
showEnvVarsInLog = 0;
};
/* End PBXShellScriptBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
97C146EA1CF9000F007C117D /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */,
1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin PBXVariantGroup section */
97C146FA1CF9000F007C117D /* Main.storyboard */ = {
isa = PBXVariantGroup;
children = (
97C146FB1CF9000F007C117D /* Base */,
);
name = Main.storyboard;
sourceTree = "<group>";
};
97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = {
isa = PBXVariantGroup;
children = (
97C147001CF9000F007C117D /* Base */,
);
name = LaunchScreen.storyboard;
sourceTree = "<group>";
};
/* End PBXVariantGroup section */
/* Begin XCBuildConfiguration section */
249021D3217E4FDB00AE95B9 /* Profile */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
SUPPORTED_PLATFORMS = iphoneos;
TARGETED_DEVICE_FAMILY = "1,2";
VALIDATE_PRODUCT = YES;
};
name = Profile;
};
249021D4217E4FDB00AE95B9 /* Profile */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
ENABLE_BITCODE = NO;
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
"$(PROJECT_DIR)/Flutter",
);
INFOPLIST_FILE = Runner/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
LIBRARY_SEARCH_PATHS = (
"$(inherited)",
"$(PROJECT_DIR)/Flutter",
);
PRODUCT_BUNDLE_IDENTIFIER = com.firstfloorsoftware.flutterSodiumExample;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
SWIFT_VERSION = 5.0;
VERSIONING_SYSTEM = "apple-generic";
};
name = Profile;
};
97C147031CF9000F007C117D /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = dwarf;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_DYNAMIC_NO_PIC = NO;
GCC_NO_COMMON_BLOCKS = YES;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1",
"$(inherited)",
);
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = iphoneos;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Debug;
};
97C147041CF9000F007C117D /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
SUPPORTED_PLATFORMS = iphoneos;
SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
TARGETED_DEVICE_FAMILY = "1,2";
VALIDATE_PRODUCT = YES;
};
name = Release;
};
97C147061CF9000F007C117D /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
ENABLE_BITCODE = NO;
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
"$(PROJECT_DIR)/Flutter",
);
INFOPLIST_FILE = Runner/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
LIBRARY_SEARCH_PATHS = (
"$(inherited)",
"$(PROJECT_DIR)/Flutter",
);
PRODUCT_BUNDLE_IDENTIFIER = com.firstfloorsoftware.flutterSodiumExample;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 5.0;
VERSIONING_SYSTEM = "apple-generic";
};
name = Debug;
};
97C147071CF9000F007C117D /* Release */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
ENABLE_BITCODE = NO;
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
"$(PROJECT_DIR)/Flutter",
);
INFOPLIST_FILE = Runner/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
LIBRARY_SEARCH_PATHS = (
"$(inherited)",
"$(PROJECT_DIR)/Flutter",
);
PRODUCT_BUNDLE_IDENTIFIER = com.firstfloorsoftware.flutterSodiumExample;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
SWIFT_VERSION = 5.0;
VERSIONING_SYSTEM = "apple-generic";
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = {
isa = XCConfigurationList;
buildConfigurations = (
97C147031CF9000F007C117D /* Debug */,
97C147041CF9000F007C117D /* Release */,
249021D3217E4FDB00AE95B9 /* Profile */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = {
isa = XCConfigurationList;
buildConfigurations = (
97C147061CF9000F007C117D /* Debug */,
97C147071CF9000F007C117D /* Release */,
249021D4217E4FDB00AE95B9 /* Profile */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
};
rootObject = 97C146E61CF9000F007C117D /* Project object */;
}

View file

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "self:">
</FileRef>
</Workspace>

View file

@ -0,0 +1,91 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1020"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "97C146ED1CF9000F007C117D"
BuildableName = "Runner.app"
BlueprintName = "Runner"
ReferencedContainer = "container:Runner.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
</Testables>
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "97C146ED1CF9000F007C117D"
BuildableName = "Runner.app"
BlueprintName = "Runner"
ReferencedContainer = "container:Runner.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "97C146ED1CF9000F007C117D"
BuildableName = "Runner.app"
BlueprintName = "Runner"
ReferencedContainer = "container:Runner.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
buildConfiguration = "Profile"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "97C146ED1CF9000F007C117D"
BuildableName = "Runner.app"
BlueprintName = "Runner"
ReferencedContainer = "container:Runner.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>

View file

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "group:Runner.xcodeproj">
</FileRef>
<FileRef
location = "group:Pods/Pods.xcodeproj">
</FileRef>
</Workspace>

View file

@ -0,0 +1,13 @@
import UIKit
import Flutter
@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {
override func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
GeneratedPluginRegistrant.register(with: self)
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
}
}

View file

@ -0,0 +1,122 @@
{
"images" : [
{
"size" : "20x20",
"idiom" : "iphone",
"filename" : "Icon-App-20x20@2x.png",
"scale" : "2x"
},
{
"size" : "20x20",
"idiom" : "iphone",
"filename" : "Icon-App-20x20@3x.png",
"scale" : "3x"
},
{
"size" : "29x29",
"idiom" : "iphone",
"filename" : "Icon-App-29x29@1x.png",
"scale" : "1x"
},
{
"size" : "29x29",
"idiom" : "iphone",
"filename" : "Icon-App-29x29@2x.png",
"scale" : "2x"
},
{
"size" : "29x29",
"idiom" : "iphone",
"filename" : "Icon-App-29x29@3x.png",
"scale" : "3x"
},
{
"size" : "40x40",
"idiom" : "iphone",
"filename" : "Icon-App-40x40@2x.png",
"scale" : "2x"
},
{
"size" : "40x40",
"idiom" : "iphone",
"filename" : "Icon-App-40x40@3x.png",
"scale" : "3x"
},
{
"size" : "60x60",
"idiom" : "iphone",
"filename" : "Icon-App-60x60@2x.png",
"scale" : "2x"
},
{
"size" : "60x60",
"idiom" : "iphone",
"filename" : "Icon-App-60x60@3x.png",
"scale" : "3x"
},
{
"size" : "20x20",
"idiom" : "ipad",
"filename" : "Icon-App-20x20@1x.png",
"scale" : "1x"
},
{
"size" : "20x20",
"idiom" : "ipad",
"filename" : "Icon-App-20x20@2x.png",
"scale" : "2x"
},
{
"size" : "29x29",
"idiom" : "ipad",
"filename" : "Icon-App-29x29@1x.png",
"scale" : "1x"
},
{
"size" : "29x29",
"idiom" : "ipad",
"filename" : "Icon-App-29x29@2x.png",
"scale" : "2x"
},
{
"size" : "40x40",
"idiom" : "ipad",
"filename" : "Icon-App-40x40@1x.png",
"scale" : "1x"
},
{
"size" : "40x40",
"idiom" : "ipad",
"filename" : "Icon-App-40x40@2x.png",
"scale" : "2x"
},
{
"size" : "76x76",
"idiom" : "ipad",
"filename" : "Icon-App-76x76@1x.png",
"scale" : "1x"
},
{
"size" : "76x76",
"idiom" : "ipad",
"filename" : "Icon-App-76x76@2x.png",
"scale" : "2x"
},
{
"size" : "83.5x83.5",
"idiom" : "ipad",
"filename" : "Icon-App-83.5x83.5@2x.png",
"scale" : "2x"
},
{
"size" : "1024x1024",
"idiom" : "ios-marketing",
"filename" : "Icon-App-1024x1024@1x.png",
"scale" : "1x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 564 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

View file

@ -0,0 +1,23 @@
{
"images" : [
{
"idiom" : "universal",
"filename" : "LaunchImage.png",
"scale" : "1x"
},
{
"idiom" : "universal",
"filename" : "LaunchImage@2x.png",
"scale" : "2x"
},
{
"idiom" : "universal",
"filename" : "LaunchImage@3x.png",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 68 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 68 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 68 B

View file

@ -0,0 +1,5 @@
# Launch Screen Assets
You can customize the launch screen with your own desired assets by replacing the image files in this directory.
You can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images.

View file

@ -0,0 +1,37 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="12121" systemVersion="16G29" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" colorMatched="YES" initialViewController="01J-lp-oVM">
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="12089"/>
</dependencies>
<scenes>
<!--View Controller-->
<scene sceneID="EHf-IW-A2E">
<objects>
<viewController id="01J-lp-oVM" sceneMemberID="viewController">
<layoutGuides>
<viewControllerLayoutGuide type="top" id="Ydg-fD-yQy"/>
<viewControllerLayoutGuide type="bottom" id="xbc-2k-c8Z"/>
</layoutGuides>
<view key="view" contentMode="scaleToFill" id="Ze5-6b-2t3">
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<imageView opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" image="LaunchImage" translatesAutoresizingMaskIntoConstraints="NO" id="YRO-k0-Ey4">
</imageView>
</subviews>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<constraints>
<constraint firstItem="YRO-k0-Ey4" firstAttribute="centerX" secondItem="Ze5-6b-2t3" secondAttribute="centerX" id="1a2-6s-vTC"/>
<constraint firstItem="YRO-k0-Ey4" firstAttribute="centerY" secondItem="Ze5-6b-2t3" secondAttribute="centerY" id="4X2-HB-R7a"/>
</constraints>
</view>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="iYj-Kq-Ea1" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="53" y="375"/>
</scene>
</scenes>
<resources>
<image name="LaunchImage" width="168" height="185"/>
</resources>
</document>

View file

@ -0,0 +1,26 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="10117" systemVersion="15F34" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" initialViewController="BYZ-38-t0r">
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="10085"/>
</dependencies>
<scenes>
<!--Flutter View Controller-->
<scene sceneID="tne-QT-ifu">
<objects>
<viewController id="BYZ-38-t0r" customClass="FlutterViewController" sceneMemberID="viewController">
<layoutGuides>
<viewControllerLayoutGuide type="top" id="y3c-jy-aDJ"/>
<viewControllerLayoutGuide type="bottom" id="wfy-db-euE"/>
</layoutGuides>
<view key="view" contentMode="scaleToFill" id="8bC-Xf-vdC">
<rect key="frame" x="0.0" y="0.0" width="600" height="600"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
</view>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="dkx-z0-nzr" sceneMemberID="firstResponder"/>
</objects>
</scene>
</scenes>
</document>

View file

@ -0,0 +1,45 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>$(DEVELOPMENT_LANGUAGE)</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>flutter_sodium_example</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>$(FLUTTER_BUILD_NAME)</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>$(FLUTTER_BUILD_NUMBER)</string>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>UILaunchStoryboardName</key>
<string>LaunchScreen</string>
<key>UIMainStoryboardFile</key>
<string>Main</string>
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>UISupportedInterfaceOrientations~ipad</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationPortraitUpsideDown</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>UIViewControllerBasedStatusBarAppearance</key>
<false/>
</dict>
</plist>

View file

@ -0,0 +1 @@
#import "GeneratedPluginRegistrant.h"

View file

@ -0,0 +1,66 @@
import 'package:flutter/material.dart';
import 'package:flutter_sodium/flutter_sodium.dart';
import 'toc.dart';
import 'topic_page.dart';
void main() {
Sodium.init();
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'flutter_sodium',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: HomePage(),
);
}
}
class HomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('flutter_sodium'),
),
body: SafeArea(
child: FutureBuilder(
// build table of contents
future: buildToc(context),
builder: (BuildContext context,
AsyncSnapshot<List<Topic>> snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
return snapshot.hasError
? Text("Build TOC failed\n\n${snapshot.error}")
: ListView(children: <Widget>[
if (snapshot.hasData)
for (var topic in snapshot.data!)
if (topic is Section)
ListTile(
title: Text(topic.title,
style: Theme.of(context)
.textTheme
.headline6))
else
ListTile(
title: Text(topic.title),
trailing: Icon(Icons.arrow_forward_ios,
size: 12.0),
onTap: () => Navigator.push(
context,
MaterialPageRoute(
builder: (context) =>
TopicPage(topic))))
]);
}
return Container();
})));
}
}

View file

@ -0,0 +1,128 @@
import 'package:flutter/material.dart';
import 'toc.dart';
class SampleWidget extends StatelessWidget {
final Sample sample;
SampleWidget(this.sample);
@override
Widget build(BuildContext context) {
return Column(crossAxisAlignment: CrossAxisAlignment.start, children: [
Padding(
padding: EdgeInsets.symmetric(vertical: 16.0),
child: Text(sample.title ?? '(no title)',
style: Theme.of(context).textTheme.headline5)),
if (sample.description != null && sample.description!.length > 0)
Padding(
padding: EdgeInsets.only(bottom: 16.0),
child: Text(sample.description!),
),
CodeBlock(sample.code),
SampleRunner(sample)
]);
}
}
class SampleRunner extends StatefulWidget {
final Sample sample;
SampleRunner(this.sample);
@override
State<StatefulWidget> createState() => _SampleRunnerState();
}
class _SampleRunnerState extends State<SampleRunner> {
Future<String>? _sampleRun;
void _runSample() {
setState(() {
_sampleRun = _runSampleHost();
});
}
Future<String> _runSampleHost() async {
final out = StringBuffer();
// run sync or async code sample
if (widget.sample.funcAsync != null) {
await widget.sample.funcAsync!((o) => out.writeln(o));
} else if (widget.sample.func != null) {
widget.sample.func!((o) => out.writeln(o));
}
return out.toString().trim();
}
@override
Widget build(BuildContext context) {
if (_sampleRun == null) {
return Padding(
padding: EdgeInsets.only(top: 16.0), child: RunButton(_runSample));
}
return FutureBuilder(
future: _sampleRun,
builder: (BuildContext context, AsyncSnapshot<String> snapshot) =>
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Padding(
padding: EdgeInsets.symmetric(vertical: 16.0),
child: RunButton(
snapshot.connectionState == ConnectionState.done
? _runSample
: null)),
Padding(
padding: EdgeInsets.only(bottom: 16.0),
child: Text('Result',
style: Theme.of(context).textTheme.headline6)),
// display progress only for async code snippets
if (widget.sample.funcAsync != null &&
snapshot.connectionState != ConnectionState.done)
LinearProgressIndicator(),
AnimatedOpacity(
opacity: snapshot.connectionState == ConnectionState.done
? 1
: 0,
duration: Duration(
milliseconds:
snapshot.connectionState == ConnectionState.done
? 150
: 50),
child: CodeBlock(
snapshot.hasError
? snapshot.error.toString()
: snapshot.data,
color: snapshot.hasError
? Colors.red.shade200
: Colors.green.shade200)),
]));
}
}
class RunButton extends StatelessWidget {
final VoidCallback? onPressed;
RunButton(this.onPressed);
@override
Widget build(BuildContext context) {
return ElevatedButton(child: Text('Run'), onPressed: onPressed);
}
}
class CodeBlock extends StatelessWidget {
final String? _code;
final Color color;
CodeBlock(this._code, {this.color = Colors.black12});
@override
Widget build(BuildContext context) {
return Container(
padding: EdgeInsets.all(10.0),
color: color,
child: Text(_code ?? '(code not found)',
style: TextStyle(fontFamily: 'RobotoMono', fontSize: 12.0)));
}
}

View file

@ -0,0 +1,733 @@
import 'dart:convert';
import 'package:flutter/foundation.dart';
import 'package:flutter_sodium/flutter_sodium.dart';
class Samples {
final salt = PasswordHash.randomSalt();
void api1(Function(Object) print) {
// BEGIN api1: Core API: Compute a password hash using the Core API with predefined salt.
final p = utf8.encoder.convert('hello world');
final h = Sodium.cryptoPwhash(
Sodium.cryptoPwhashBytesMin,
p,
salt,
Sodium.cryptoPwhashOpslimitInteractive,
Sodium.cryptoPwhashMemlimitInteractive,
Sodium.cryptoPwhashAlgDefault);
print('salt: ${Sodium.bin2hex(salt)}');
print('hash: ${Sodium.bin2hex(h)}');
// END api1
}
void api2(Function(Object) print) {
// BEGIN api2: High-level API: Compute a password hash using the high-level API with predefined salt.
final p = 'hello world';
final h = PasswordHash.hashString(p, salt);
print('salt: ${Sodium.bin2hex(salt)}');
print('hash: ${Sodium.bin2hex(h)}');
// END api2
}
void random1(Function(Object) print) {
// BEGIN random1: Random: Returns an unpredictable value between 0 and 0xffffffff (included).
final r = RandomBytes.random();
print(r.toRadixString(16));
// END random1
}
void random2(Function(Object) print) {
// BEGIN random2: Uniform: Generates an unpredictable value between 0 and upperBound (excluded)
final r = RandomBytes.uniform(16);
print(r);
// END random2
}
void random3(Function(Object) print) {
// BEGIN random3: Buffer: Generates an unpredictable sequence of bytes of specified size.
final b = RandomBytes.buffer(16);
print(Sodium.bin2hex(b));
// END random3
}
void about1(Function(Object) print) {
// BEGIN about1: Version: Retrieves the version details of the loaded libsodium library.
final v = Sodium.versionString;
final v1 = Sodium.libraryVersionMajor;
final v2 = Sodium.libraryVersionMinor;
final m = Sodium.libraryMinimal;
print('$v ($v1.$v2), minimal: $m');
// END about1
}
void about2(Function(Object) print) {
// BEGIN about2: Primitives: Retrieves the names of the algorithms used in the various libsodium APIs.
print('crypto_auth: ${Sodium.cryptoAuthPrimitive}');
print('crypto_box: ${Sodium.cryptoBoxPrimitive}');
print('crypto_generichash: ${Sodium.cryptoGenerichashPrimitive}');
print('crypto_hash: ${Sodium.cryptoHashPrimitive}');
print('crypto_kdf: ${Sodium.cryptoKdfPrimitive}');
print('crypto_kx: ${Sodium.cryptoKxPrimitive}');
print('crypto_onetimeauth: ${Sodium.cryptoOnetimeauthPrimitive}');
print('crypto_pwhash: ${Sodium.cryptoPwhashPrimitive}');
print('crypto_scalarmult: ${Sodium.cryptoScalarmultPrimitive}');
print('crypto_secretbox: ${Sodium.cryptoSecretboxPrimitive}');
print('crypto_shorthash: ${Sodium.cryptoShorthashPrimitive}');
print('crypto_sign: ${Sodium.cryptoSignPrimitive}');
print('crypto_stream: ${Sodium.cryptoStreamPrimitive}');
print('randombytes: ${Sodium.randombytesImplementationName}');
// END about2
}
void about3(Function(Object) print) {
// BEGIN about3: Runtime: Retrieves CPU capabilities
print('neon: ${Sodium.runtimeHasNeon}');
//print('armcrypto: ${Sodium.runtimeHasArmcrypto}');
print('sse2: ${Sodium.runtimeHasSse2}');
print('sse3: ${Sodium.runtimeHasSse3}');
print('ssse3: ${Sodium.runtimeHasSsse3}');
print('sse41: ${Sodium.runtimeHasSse41}');
print('avx: ${Sodium.runtimeHasAvx}');
print('avx2: ${Sodium.runtimeHasAvx2}');
print('avx512f: ${Sodium.runtimeHasAvx512f}');
print('pclmul: ${Sodium.runtimeHasPclmul}');
print('aesni: ${Sodium.runtimeHasAesni}');
print('rdrand: ${Sodium.runtimeHasRdrand}');
// END about3
}
void encoding1(Function(Object) print) {
// BEGIN encoding1: Hexadecimal encoding: Converts byte sequence to hexadecimal string and vice versa.
final r = Sodium.randombytesBuf(16);
// to hex
final h = Sodium.bin2hex(r);
print(h);
// and back to binary
final b = Sodium.hex2bin(h);
// assert equality
assert(Sodium.memcmp(r, b));
// END encoding1
}
void encoding2(Function(Object) print) {
// BEGIN encoding2: Base64 encoding: Converts byte sequence to base64 string and vice versa. Support multiple base64 variants
final r = Sodium.randombytesBuf(16);
// to base64
final h = Sodium.bin2base64(r);
print(h);
// and back to binary
final b = Sodium.base642bin(h);
// assert equality
assert(Sodium.memcmp(r, b));
// END encoding2
}
void padding1(Function(Object) print) {
// BEGIN padding1: Usage: Appends padding data using the ISO/IEC 7816-4 padding algorithm.
final b = Sodium.randombytesBuf(10);
// add padding
final p = Sodium.pad(b, 16);
print(Sodium.bin2hex(b));
print(Sodium.bin2hex(p));
// remove padding
final r = Sodium.unpad(p, 16);
// b and r should be equal
assert(Sodium.memcmp(b, r));
// END padding1
}
void auth1(Function(Object) print) {
// BEGIN auth1: Usage: Secret key authentication
// generate secret
final k = CryptoAuth.randomKey();
// compute tag
final m = 'hello world';
final t = CryptoAuth.computeString(m, k);
print(Sodium.bin2hex(t));
// verify tag
final v = CryptoAuth.verifyString(t, m, k);
assert(v);
// END auth1
}
void box1(Function(Object) print) {
// BEGIN box1: Combined mode: The authentication tag and the encrypted message are stored together.
// Generate key pairs
final a = CryptoBox.randomKeys();
final b = CryptoBox.randomKeys();
final n = CryptoBox.randomNonce();
// Alice encrypts message for Bob
final m = 'hello world';
final e = CryptoBox.encryptString(m, n, b.pk, a.sk);
print(Sodium.bin2hex(e));
// Bob decrypts message from Alice
final d = CryptoBox.decryptString(e, n, a.pk, b.sk);
assert(m == d);
print('decrypted: $d');
// END box1
}
void box2(Function(Object) print) {
// BEGIN box2: Detached mode: The authentication tag and the encrypted message are detached so they can be stored at different locations.
// Generate key pairs
final a = CryptoBox.randomKeys();
final b = CryptoBox.randomKeys();
final n = CryptoBox.randomNonce();
// Alice encrypts message for Bob
final m = 'hello world';
final c = CryptoBox.encryptStringDetached(m, n, b.pk, a.sk);
print('cipher: ${Sodium.bin2hex(c.c)}');
print('mac: ${Sodium.bin2hex(c.mac)}');
// Bob decrypts message from Alice
final d = CryptoBox.decryptStringDetached(c.c, c.mac, n, a.pk, b.sk);
assert(m == d);
print('decrypted: $d');
// END box2
}
void box3(Function(Object) print) {
// BEGIN box3: Precalculated combined mode: The authentication tag and the encrypted message are stored together.
// Generate key pairs
final a = CryptoBox.randomKeys();
final b = CryptoBox.randomKeys();
final n = CryptoBox.randomNonce();
// Alice encrypts message for Bob
final m = 'hello world';
final e = CryptoBox.encryptString(m, n, b.pk, a.sk);
print(Sodium.bin2hex(e));
// Bob decrypts message from Alice (precalculated)
final k = CryptoBox.sharedSecret(a.pk, b.sk);
final d = CryptoBox.decryptStringAfternm(e, n, k);
assert(m == d);
print('decrypted: $d');
// END box3
}
void box4(Function(Object) print) {
// BEGIN box4: Precalculated detached mode: The authentication tag and the encrypted message are detached so they can be stored at different locations.
// Generate key pairs
final a = CryptoBox.randomKeys();
final b = CryptoBox.randomKeys();
final n = CryptoBox.randomNonce();
// Alice encrypts message for Bob (precalculated)
final k = CryptoBox.sharedSecret(b.pk, a.sk);
final m = 'hello world';
final c = CryptoBox.encryptStringDetachedAfternm(m, n, k);
print('cipher: ${Sodium.bin2hex(c.c)}');
print('mac: ${Sodium.bin2hex(c.mac)}');
// Bob decrypts message from Alice
final d = CryptoBox.decryptStringDetached(c.c, c.mac, n, a.pk, b.sk);
assert(m == d);
print('decrypted: $d');
// END box4
}
void box5(Function(Object) print) {
// BEGIN box5: Usage: Anonymous sender encrypts a message intended for recipient only.
// Recipient creates a long-term key pair
final k = SealedBox.randomKeys();
// Anonymous sender encrypts a message using an ephemeral key pair and the recipient's public key
final m = 'hello world';
final c = SealedBox.sealString(m, k.pk);
print('cipher: ${Sodium.bin2hex(c)}');
// Recipient decrypts the ciphertext
final d = SealedBox.openString(c, k);
assert(m == d);
print('decrypted: $d');
// END box5
}
void secret1(Function(Object) print) {
// BEGIN secret1: Combined mode: The authentication tag and the encrypted message are stored together.
// Generate random secret and nonce
final k = SecretBox.randomKey();
final n = SecretBox.randomNonce();
// encrypt
final m = 'hello world';
final e = SecretBox.encryptString(m, n, k);
print(Sodium.bin2hex(e));
// decrypt
final d = SecretBox.decryptString(e, n, k);
assert(m == d);
// END secret1
}
void secret2(Function(Object) print) {
// BEGIN secret2: Detached mode: The authentication tag and the encrypted message are detached so they can be stored at different locations.
// Generate random secret and nonce
final k = SecretBox.randomKey();
final n = SecretBox.randomNonce();
// encrypt
final m = 'hello world';
final c = SecretBox.encryptStringDetached(m, n, k);
print('cipher: ${Sodium.bin2hex(c.c)}');
print('mac: ${Sodium.bin2hex(c.mac)}');
// decrypt
final d = SecretBox.decryptStringDetached(c.c, c.mac, n, k);
assert(m == d);
// END secret2
}
void sign1(Function(Object) print) {
// BEGIN sign1: Combined mode: Compute a signed message
final m = 'hello world';
final k = CryptoSign.randomKeys();
// sign with secret key
final s = CryptoSign.signString(m, k.sk);
print('signed: ${Sodium.bin2hex(s)}');
// verify with public key
final u = CryptoSign.openString(s, k.pk);
print('unsigned: $u');
assert(m == u);
// END sign1
}
void sign2(Function(Object) print) {
// BEGIN sign2: Detached mode: Compute a signature
// Author generates keypair
final k = CryptoSign.randomKeys();
// Author computes signature using secret key
final m = 'hello world';
final s = CryptoSign.signStringDetached(m, k.sk);
print(Sodium.bin2hex(s));
// Recipient verifies message was issued by author using public key
final v = CryptoSign.verifyString(s, m, k.pk);
assert(v);
// END sign2
}
Future sign3(Function(Object) print) async {
// BEGIN sign3: Multi-part message: Compute a signature for multiple messages.
// Author generates keypair
final k = CryptoSign.randomKeys();
// Author computes signature using secret key
final p = ['Arbitrary data to hash', 'is longer than expected'];
final s = await CryptoSign.signStrings(Stream.fromIterable(p), k.sk);
print(Sodium.bin2hex(s));
// Recipient verifies message was issued by author using public key
final v = await CryptoSign.verifyStrings(s, Stream.fromIterable(p), k.pk);
assert(v);
// END sign3
}
void sign4(Function(Object) print) {
// BEGIN sign4: Secret key extraction: Extracts seed and public key from a secret key.
final s = CryptoSign.randomSeed();
final k = CryptoSign.seedKeys(s);
print('seed: ${Sodium.bin2hex(s)}');
print('pk: ${Sodium.bin2hex(k.pk)}');
print('sk: ${Sodium.bin2hex(k.sk)}');
final s2 = CryptoSign.extractSeed(k.sk);
final pk = CryptoSign.extractPublicKey(k.sk);
// assert equality
assert(Sodium.memcmp(s, s2));
assert(Sodium.memcmp(pk, k.pk));
// END sign4
}
void sign5(Function(Object) print) {
// BEGIN sign5: Usage: Converts an Ed25519 key pair to a Curve25519 key pair.
final k = CryptoSign.randomKeys();
print('ed25519 pk: ${Sodium.bin2hex(k.pk)}');
print('ed25519 sk: ${Sodium.bin2hex(k.sk)}');
final pk = Sodium.cryptoSignEd25519PkToCurve25519(k.pk);
final sk = Sodium.cryptoSignEd25519SkToCurve25519(k.sk);
print('curve25519 pk: ${Sodium.bin2hex(pk)}');
print('curve25519 sk: ${Sodium.bin2hex(sk)}');
// END sign5
}
void generic1(Function(Object) print) {
// BEGIN generic1: Single-part without a key:
final v = 'Arbitrary data to hash';
final h = GenericHash.hashString(v);
print(Sodium.bin2hex(h));
// END generic1
}
void generic2(Function(Object) print) {
// BEGIN generic2: Single-part with a key:
final v = 'Arbitrary data to hash';
final k = GenericHash.randomKey();
final h = GenericHash.hashString(v, key: k);
print(Sodium.bin2hex(h));
// END generic2
}
Future generic3(Function(Object) print) async {
// BEGIN generic3: Multi-part without a key: Should result in a hash equal to the single-part without a key sample.
final s = Stream.fromIterable(['Arbitrary data ', 'to hash']);
final h = await GenericHash.hashStrings(s);
print(Sodium.bin2hex(h));
// END generic3
}
Future generic4(Function(Object) print) async {
// BEGIN generic4: Multi-part with a key:
final s = Stream.fromIterable(
['Arbitrary data to hash', 'is longer than expected']);
final k = GenericHash.randomKey();
final h = await GenericHash.hashStrings(s, key: k);
print(Sodium.bin2hex(h));
// END generic4
}
void pwhash1(Function(Object) print) {
// BEGIN pwhash1: Hash: Derives a hash from given password and salt.
final p = 'hello world';
final s = PasswordHash.randomSalt();
final h = PasswordHash.hashString(p, s);
print(Sodium.bin2hex(h));
// END pwhash1
}
void pwhash2(Function(Object) print) {
// BEGIN pwhash2: Hash storage: Computes a password verification string for given password.
final p = 'hello world';
final s = PasswordHash.hashStringStorage(p);
print(s);
// verify storage string
final v = PasswordHash.verifyStorage(s, p);
print('Valid: $v');
// END pwhash2
}
Future pwhash3(Function(Object) print) async {
// BEGIN pwhash3: Hash storage async: Execute long running hash operation in background using Flutter's compute.
// time operation
final w = Stopwatch();
w.start();
// compute hash
final p = 'hello world';
final s = await compute(PasswordHash.hashStringStorageModerate, p);
print(s);
print('Compute took ${w.elapsedMilliseconds}ms');
w.stop();
// END pwhash3
}
void shorthash1(Function(Object) print) {
// BEGIN shorthash1: Usage: Computes a fixed-size fingerprint for given string value and key.
final m = 'hello world';
final k = ShortHash.randomKey();
final h = ShortHash.hashString(m, k);
print(Sodium.bin2hex(h));
// END shorthash1
}
void kdf1(Function(Object) print) {
// BEGIN kdf1: Usage: Derive subkeys.
// random master key
final k = KeyDerivation.randomKey();
// derives subkeys of various lengths
final k1 = KeyDerivation.derive(k, 1, subKeyLength: 32);
final k2 = KeyDerivation.derive(k, 2, subKeyLength: 32);
final k3 = KeyDerivation.derive(k, 3, subKeyLength: 64);
print('subkey1: ${Sodium.bin2hex(k1)}');
print('subkey2: ${Sodium.bin2hex(k2)}');
print('subkey3: ${Sodium.bin2hex(k3)}');
// END kdf1
}
void kx1(Function(Object) print) {
// BEGIN kx1: Usage: Compute a set of shared keys.
// generate key pairs
final c = KeyExchange.randomKeys();
final s = KeyExchange.randomKeys();
// compute session keys
final ck = KeyExchange.computeClientSessionKeys(c, s.pk);
final sk = KeyExchange.computeServerSessionKeys(s, c.pk);
// assert keys do match
assert(Sodium.memcmp(ck.rx, sk.tx));
assert(Sodium.memcmp(ck.tx, sk.rx));
print('client rx: ${Sodium.bin2hex(ck.rx)}');
print('client tx: ${Sodium.bin2hex(ck.tx)}');
// END kx1
}
Future scalarmult1(Function(Object) print) async {
// BEGIN scalarmult1: Usage: Computes a shared secret.
// client keys
final csk = ScalarMult.randomSecretKey();
final cpk = ScalarMult.computePublicKey(csk);
// server keys
final ssk = ScalarMult.randomSecretKey();
final spk = ScalarMult.computePublicKey(ssk);
// client derives shared key
final cq = ScalarMult.computeSharedSecret(csk, spk);
final cs =
await GenericHash.hashStream(Stream.fromIterable([cq, cpk, spk]));
// server derives shared key
final sq = ScalarMult.computeSharedSecret(ssk, cpk);
final ss =
await GenericHash.hashStream(Stream.fromIterable([sq, cpk, spk]));
// assert shared keys do match
assert(Sodium.memcmp(cs, ss));
print(Sodium.bin2hex(cs));
// END scalarmult1
}
void chacha1(Function(Object) print) {
// BEGIN chacha1: Combined mode: The authentication tag is directly appended to the encrypted message.
// random nonce and key
final n = ChaCha20Poly1305.randomNonce();
final k = ChaCha20Poly1305.randomKey();
print('nonce: ${Sodium.bin2hex(n)}');
print('key: ${Sodium.bin2hex(k)}');
// encrypt
final m = 'hello world';
final d = '123456';
final c = ChaCha20Poly1305.encryptString(m, n, k, additionalData: d);
print('cipher: ${Sodium.bin2hex(c)}');
// decrypt
final s = ChaCha20Poly1305.decryptString(c, n, k, additionalData: d);
assert(m == s);
// END chacha1
}
void chacha2(Function(Object) print) {
// BEGIN chacha2: Detached mode: The authentication tag and the encrypted message are detached so they can be stored at different locations.
// random nonce and key
final n = ChaCha20Poly1305.randomNonce();
final k = ChaCha20Poly1305.randomKey();
print('nonce: ${Sodium.bin2hex(n)}');
print('key: ${Sodium.bin2hex(k)}');
// encrypt
final m = 'hello world';
final d = '123456';
final c =
ChaCha20Poly1305.encryptStringDetached(m, n, k, additionalData: d);
print('cipher: ${Sodium.bin2hex(c.c)}');
print('mac: ${Sodium.bin2hex(c.mac)}');
// decrypt
final s = ChaCha20Poly1305.decryptStringDetached(c.c, c.mac, n, k,
additionalData: d);
assert(m == s);
// END chacha2
}
void chachaietf1(Function(Object) print) {
// BEGIN chachaietf1: Combined mode: The authentication tag is directly appended to the encrypted message.
// random nonce and key
final n = ChaCha20Poly1305Ietf.randomNonce();
final k = ChaCha20Poly1305Ietf.randomKey();
print('nonce: ${Sodium.bin2hex(n)}');
print('key: ${Sodium.bin2hex(k)}');
// encrypt
final m = 'hello world';
final d = '123456';
final c = ChaCha20Poly1305Ietf.encryptString(m, n, k, additionalData: d);
print('cipher: ${Sodium.bin2hex(c)}');
// decrypt
final s = ChaCha20Poly1305Ietf.decryptString(c, n, k, additionalData: d);
assert(m == s);
// END chachaietf1
}
void chachaietf2(Function(Object) print) {
// BEGIN chachaietf2: Detached mode: The authentication tag and the encrypted message are detached so they can be stored at different locations.
// random nonce and key
final n = ChaCha20Poly1305Ietf.randomNonce();
final k = ChaCha20Poly1305Ietf.randomKey();
print('nonce: ${Sodium.bin2hex(n)}');
print('key: ${Sodium.bin2hex(k)}');
// encrypt
final m = 'hello world';
final d = '123456';
final c =
ChaCha20Poly1305Ietf.encryptStringDetached(m, n, k, additionalData: d);
print('cipher: ${Sodium.bin2hex(c.c)}');
print('mac: ${Sodium.bin2hex(c.mac)}');
// decrypt
final s = ChaCha20Poly1305Ietf.decryptStringDetached(c.c, c.mac, n, k,
additionalData: d);
assert(m == s);
// END chachaietf2
}
void xchachaietf1(Function(Object) print) {
// BEGIN xchachaietf1: Combined mode: The authentication tag is directly appended to the encrypted message.
// random nonce and key
final n = XChaCha20Poly1305Ietf.randomNonce();
final k = XChaCha20Poly1305Ietf.randomKey();
print('nonce: ${Sodium.bin2hex(n)}');
print('key: ${Sodium.bin2hex(k)}');
// encrypt
final m = 'hello world';
final d = '123456';
final c = XChaCha20Poly1305Ietf.encryptString(m, n, k, additionalData: d);
print('cipher: ${Sodium.bin2hex(c)}');
// decrypt
final s = XChaCha20Poly1305Ietf.decryptString(c, n, k, additionalData: d);
assert(m == s);
// END xchachaietf1
}
void xchachaietf2(Function(Object) print) {
// BEGIN xchachaietf2: Detached mode: The authentication tag and the encrypted message are detached so they can be stored at different locations.
// random nonce and key
final n = XChaCha20Poly1305Ietf.randomNonce();
final k = XChaCha20Poly1305Ietf.randomKey();
print('nonce: ${Sodium.bin2hex(n)}');
print('key: ${Sodium.bin2hex(k)}');
// encrypt
final m = 'hello world';
final d = '123456';
final c =
XChaCha20Poly1305Ietf.encryptStringDetached(m, n, k, additionalData: d);
print('cipher: ${Sodium.bin2hex(c.c)}');
print('mac: ${Sodium.bin2hex(c.mac)}');
// decrypt
final s = XChaCha20Poly1305Ietf.decryptStringDetached(c.c, c.mac, n, k,
additionalData: d);
assert(m == s);
// END xchachaietf2
}
void onetime1(Function(Object) print) {
// BEGIN onetime1: Single-part:
final m = 'hello world';
final k = OnetimeAuth.randomKey();
final t = OnetimeAuth.computeString(m, k);
print(Sodium.bin2hex(t));
// verify tag
final valid = OnetimeAuth.verifyString(t, m, k);
assert(valid);
// END onetime1
}
Future onetime2(Function(Object) print) async {
// BEGIN onetime2: Multi-part:
final i = Stream.fromIterable(['Muti-part', 'data']);
final k = OnetimeAuth.randomKey();
final t = await OnetimeAuth.computeStrings(i, k);
print(Sodium.bin2hex(t));
// END onetime2
}
void hash1(Function(Object) print) {
// BEGIN hash1: Usage: SHA-512 hashing
final m = 'hello world';
final h = Hash.hashString(m);
print(Sodium.bin2hex(h));
// END hash1
}
void stream1(Function(Object) print) {
// BEGIN stream1: Usage: Generate pseudo random bytes using a nonce and a secret key
// random key and nonce
final n = CryptoStream.randomNonce();
final k = CryptoStream.randomKey();
// generate 16 bytes
var c = CryptoStream.stream(16, n, k);
print(Sodium.bin2hex(c));
// use same nonce and key yields same bytes
var c2 = CryptoStream.stream(16, n, k);
// assert equality
assert(Sodium.memcmp(c, c2));
// END stream1
}
}

View file

@ -0,0 +1,267 @@
import 'dart:convert';
import 'package:flutter/material.dart';
import 'samples.dart';
typedef void SampleFunc(Function(Object) print);
typedef Future SampleFuncAsync(Function(Object) print);
class Section extends Topic {
Section(String title) : super(title);
}
class Topic {
final String title;
final String? description;
final String? url;
final List<Sample>? samples;
Topic(this.title, {this.description, this.url, this.samples});
}
class Sample {
final String name;
final SampleFunc? func;
final SampleFuncAsync? funcAsync;
String? title;
String? description;
String? code;
Sample(this.name, {this.func, this.funcAsync});
}
Future<List<Topic>> buildToc(BuildContext context) async {
final samples = Samples();
final toc = [
Section('Common'),
Topic('APIs',
description:
'The flutter_sodium library contains two sets of APIs, a core API and a high-level API. The core API maps native libsodium functions 1:1 to Dart equivalents. The high-level API provides Dart-friendly, opinionated access to libsodium.',
samples: <Sample>[
Sample('api1', func: samples.api1),
Sample('api2', func: samples.api2)
]),
Topic('Random data',
description:
'Provides a set of functions to generate unpredictable data, suitable for creating secret keys.',
url: 'https://libsodium.gitbook.io/doc/generating_random_data/',
samples: <Sample>[
Sample('random1', func: samples.random1),
Sample('random2', func: samples.random2),
Sample('random3', func: samples.random3)
]),
Topic('Encoding',
description: 'Encode byte sequence to string and vice versa.',
url: 'https://libsodium.gitbook.io/doc/helpers',
samples: <Sample>[
Sample('encoding1', func: samples.encoding1),
Sample('encoding2', func: samples.encoding2)
]),
Topic('Padding',
description: 'Append padding data',
url: 'https://libsodium.gitbook.io/doc/padding',
samples: <Sample>[Sample('padding1', func: samples.padding1)]),
Topic('About',
description: 'Provides libsodium version, runtime and algorithm info.',
url: 'https://libsodium.gitbook.io/doc/',
samples: <Sample>[
Sample('about1', func: samples.about1),
Sample('about2', func: samples.about2),
Sample('about3', func: samples.about3)
]),
Section('Secret-key cryptography'),
Topic('Authenticated encryption',
description: 'Secret-key encryption and verification',
url:
'https://libsodium.gitbook.io/doc/secret-key_cryptography/secretbox',
samples: <Sample>[
Sample('secret1', func: samples.secret1),
Sample('secret2', func: samples.secret2)
]),
Topic('Authentication',
description:
'Computes an authentication tag for a message and a secret key, and provides a way to verify that a given tag is valid for a given message and a key.',
url:
'https://libsodium.gitbook.io/doc/secret-key_cryptography/secret-key_authentication',
samples: <Sample>[
Sample('auth1', func: samples.auth1),
]),
Topic('Original ChaCha20-Poly1305',
description: 'Authenticated Encryption with Additional Data.',
url:
'https://libsodium.gitbook.io/doc/secret-key_cryptography/aead/chacha20-poly1305/original_chacha20-poly1305_construction',
samples: <Sample>[
Sample('chacha1', func: samples.chacha1),
Sample('chacha2', func: samples.chacha2)
]),
Topic('IETF ChaCha20-Poly1305',
description: 'Authenticated Encryption with Additional Data',
url:
'https://libsodium.gitbook.io/doc/secret-key_cryptography/aead/chacha20-poly1305/ietf_chacha20-poly1305_construction',
samples: <Sample>[
Sample('chachaietf1', func: samples.chachaietf1),
Sample('chachaietf2', func: samples.chachaietf2)
]),
Topic('XChaCha20-Poly1305',
description: 'Authenticated Encryption with Additional Data.',
url:
'https://libsodium.gitbook.io/doc/secret-key_cryptography/aead/chacha20-poly1305/xchacha20-poly1305_construction',
samples: <Sample>[
Sample('xchachaietf1', func: samples.xchachaietf1),
Sample('xchachaietf2', func: samples.xchachaietf2)
]),
Section('Public-key cryptography'),
Topic('Authenticated encryption',
description: 'Public-key authenticated encryption',
url:
'https://libsodium.gitbook.io/doc/public-key_cryptography/authenticated_encryption',
samples: <Sample>[
Sample('box1', func: samples.box1),
Sample('box2', func: samples.box2),
Sample('box3', func: samples.box3),
Sample('box4', func: samples.box4)
]),
Topic('Public-key signatures',
description:
'Computes a signature for a message using a secret key, and provides verification using a public key.',
url:
'https://libsodium.gitbook.io/doc/public-key_cryptography/public-key_signatures',
samples: <Sample>[
Sample('sign1', func: samples.sign1),
Sample('sign2', func: samples.sign2),
Sample('sign3', funcAsync: samples.sign3),
Sample('sign4', func: samples.sign4)
]),
Topic('Sealed boxes',
description:
'Anonymously send encrypted messages to a recipient given its public key.',
url: 'https://libsodium.gitbook.io/doc/public-key_cryptography/sealed_boxes',
samples: <Sample>[Sample('box5', func: samples.box5)]),
Section('Hashing'),
Topic('Generic hashing',
description:
'Computes a fixed-length fingerprint for an arbitrary long message using the BLAKE2b algorithm.',
url: 'https://libsodium.gitbook.io/doc/hashing/generic_hashing',
samples: <Sample>[
Sample('generic1', func: samples.generic1),
Sample('generic2', func: samples.generic2),
Sample('generic3', funcAsync: samples.generic3),
Sample('generic4', funcAsync: samples.generic4)
]),
Topic('Short-input hashing',
description: 'Computes short hashes using the SipHash-2-4 algorithm.',
url: 'https://libsodium.gitbook.io/doc/hashing/short-input_hashing',
samples: <Sample>[Sample('shorthash1', func: samples.shorthash1)]),
Topic('Password hashing',
description:
'Provides an Argon2 password hashing scheme implementation.',
url:
'https://libsodium.gitbook.io/doc/password_hashing/the_argon2i_function',
samples: <Sample>[
Sample('pwhash1', func: samples.pwhash1),
Sample('pwhash2', func: samples.pwhash2),
Sample('pwhash3', funcAsync: samples.pwhash3),
]),
Section('Key functions'),
Topic('Key derivation',
description: 'Derive secret subkeys from a single master key.',
url: 'https://libsodium.gitbook.io/doc/key_derivation/',
samples: <Sample>[Sample('kdf1', func: samples.kdf1)]),
Topic('Key exchange',
description: 'Securely compute a set of shared keys.',
url: 'https://libsodium.gitbook.io/doc/key_exchange/',
samples: <Sample>[Sample('kx1', func: samples.kx1)]),
Section('Advanced'),
Topic('SHA-2',
description: 'SHA-512 hash functions',
url: 'https://libsodium.gitbook.io/doc/advanced/sha-2_hash_function',
samples: <Sample>[Sample('hash1', func: samples.hash1)]),
Topic('Diffie-Hellman',
description: 'Perform scalar multiplication of elliptic curve points',
url: 'https://libsodium.gitbook.io/doc/advanced/scalar_multiplication',
samples: <Sample>[
Sample('scalarmult1', funcAsync: samples.scalarmult1)
]),
Topic('One-time authentication',
description: 'Secret-key single-message authentication using Poly1305',
url: 'https://libsodium.gitbook.io/doc/advanced/poly1305',
samples: <Sample>[
Sample('onetime1', func: samples.onetime1),
Sample('onetime2', funcAsync: samples.onetime2)
]),
Topic('Stream ciphers',
description: 'Generate pseudo-random data from a key',
url: 'https://libsodium.gitbook.io/doc/advanced/stream_ciphers',
samples: <Sample>[Sample('stream1', func: samples.stream1)]),
Topic('Ed25519 To Curve25519',
description:
'Ed25519 keys can be converted to X25519 keys, so that the same key pair can be used both for authenticated encryption (crypto_box) and for signatures (crypto_sign).',
url: 'https://download.libsodium.org/doc/advanced/ed25519-curve25519',
samples: <Sample>[Sample('sign5', func: samples.sign5)])
];
// load asset samples.dart for code snippets
final src =
await DefaultAssetBundle.of(context).loadString('lib/samples.dart');
// iterate all samples in the toc, and parse title, description and code snippet
for (var topic in toc) {
if (topic.samples != null) {
for (var sample in topic.samples!) {
final beginTag = '// BEGIN ${sample.name}:';
final begin = src.indexOf(beginTag);
assert(begin != -1);
// parse title
final beginTitle = begin + beginTag.length;
final endTitle = src.indexOf(':', beginTitle);
assert(endTitle != -1);
sample.title = src.substring(beginTitle, endTitle).trim();
// parse description
final endDescription = src.indexOf('\n', endTitle);
assert(endDescription != -1);
sample.description = src.substring(endTitle + 1, endDescription).trim();
final end = src.indexOf('// END ${sample.name}', endDescription);
assert(end != -1);
sample.code = _formatCode(src.substring(endDescription, end));
}
}
}
return toc;
}
String _formatCode(String code) {
final result = StringBuffer();
final lines = LineSplitter.split(code).toList();
int indent = -1;
for (var i = 0; i < lines.length; i++) {
String line = lines[i];
// skip empty first and last lines
if (line.trim().length == 0 && (i == 0 || i == lines.length - 1)) {
continue;
}
// determine indent
if (indent == -1) {
for (indent = 0; indent < line.length; indent++) {
if (line[indent] != ' ') {
break;
}
}
}
// remove indent from line
if (line.startsWith(' ' * indent)) {
line = line.substring(indent);
}
if (result.isNotEmpty) {
result.writeln();
}
result.write(line);
}
return result.toString();
}

View file

@ -0,0 +1,50 @@
import 'package:flutter/material.dart';
import 'package:flutter_sodium_example/sample_widget.dart';
import 'package:url_launcher/url_launcher.dart';
import 'toc.dart';
class TopicPage extends StatelessWidget {
final Topic topic;
TopicPage(this.topic);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(topic.title),
),
body: SafeArea(
child: SingleChildScrollView(
child: Container(
padding: EdgeInsets.all(15.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
// description
if (topic.description != null)
Padding(
padding: EdgeInsets.only(bottom: 16.0),
child: Text(topic.description!)),
// more info button
if (topic.url != null)
Padding(
padding: EdgeInsets.only(bottom: 16.0),
child: InkWell(
child: Text(
'More information',
style: TextStyle(
color: Theme.of(context).accentColor),
),
onTap: () => launch(topic.url!)),
),
// 0..n samples
if (topic.samples != null)
for (var sample in topic.samples!)
Padding(
padding: EdgeInsets.only(bottom: 16.0),
child: SampleWidget(sample))
],
)))));
}
}

View file

@ -0,0 +1,82 @@
platform :osx, '10.11'
# CocoaPods analytics sends network stats synchronously affecting flutter build latency.
ENV['COCOAPODS_DISABLE_STATS'] = 'true'
project 'Runner', {
'Debug' => :debug,
'Profile' => :release,
'Release' => :release,
}
def parse_KV_file(file, separator='=')
file_abs_path = File.expand_path(file)
if !File.exists? file_abs_path
return [];
end
pods_ary = []
skip_line_start_symbols = ["#", "/"]
File.foreach(file_abs_path) { |line|
next if skip_line_start_symbols.any? { |symbol| line =~ /^\s*#{symbol}/ }
plugin = line.split(pattern=separator)
if plugin.length == 2
podname = plugin[0].strip()
path = plugin[1].strip()
podpath = File.expand_path("#{path}", file_abs_path)
pods_ary.push({:name => podname, :path => podpath});
else
puts "Invalid plugin specification: #{line}"
end
}
return pods_ary
end
def pubspec_supports_macos(file)
file_abs_path = File.expand_path(file)
if !File.exists? file_abs_path
return false;
end
File.foreach(file_abs_path) { |line|
return true if line =~ /^\s*macos:/
}
return false
end
target 'Runner' do
use_frameworks!
use_modular_headers!
# Prepare symlinks folder. We use symlinks to avoid having Podfile.lock
# referring to absolute paths on developers' machines.
ephemeral_dir = File.join('Flutter', 'ephemeral')
symlink_dir = File.join(ephemeral_dir, '.symlinks')
symlink_plugins_dir = File.join(symlink_dir, 'plugins')
system("rm -rf #{symlink_dir}")
system("mkdir -p #{symlink_plugins_dir}")
# Flutter Pods
generated_xcconfig = parse_KV_file(File.join(ephemeral_dir, 'Flutter-Generated.xcconfig'))
if generated_xcconfig.empty?
puts "Flutter-Generated.xcconfig must exist. If you're running pod install manually, make sure flutter packages get is executed first."
end
generated_xcconfig.map { |p|
if p[:name] == 'FLUTTER_FRAMEWORK_DIR'
symlink = File.join(symlink_dir, 'flutter')
File.symlink(File.dirname(p[:path]), symlink)
pod 'FlutterMacOS', :path => File.join(symlink, File.basename(p[:path]))
end
}
# Plugin Pods
plugin_pods = parse_KV_file('../.flutter-plugins')
plugin_pods.map { |p|
symlink = File.join(symlink_plugins_dir, p[:name])
File.symlink(p[:path], symlink)
if pubspec_supports_macos(File.join(symlink, 'pubspec.yaml'))
pod p[:name], :path => File.join(symlink, 'macos')
end
}
end
# Prevent Cocoapods from embedding a second Flutter framework and causing an error with the new Xcode build system.
install! 'cocoapods', :disable_input_output_paths => true

View file

@ -0,0 +1,28 @@
name: flutter_sodium_example
version: 2.0.0
description: Demonstrates how to use the flutter_sodium plugin.
publish_to: 'none'
environment:
sdk: ">=2.12.0 <3.0.0"
dependencies:
flutter:
sdk: flutter
url_launcher: ^6.0.2
dev_dependencies:
flutter_test:
sdk: flutter
flutter_sodium:
path: ../
flutter:
uses-material-design: true
assets:
- lib/samples.dart
fonts:
- family: RobotoMono
fonts:
- asset: assets/fonts/RobotoMono-Regular.ttf

View file

@ -0,0 +1,8 @@
// This is a basic Flutter widget test.
//
// To perform an interaction with a widget in your test, use the WidgetTester
// utility that Flutter provides. For example, you can send tap and scroll
// gestures. You can also use WidgetTester to find child widgets in the widget
// tree, read text, and verify that the values of widget properties are correct.
void main() {}

View file

@ -0,0 +1,37 @@
.idea/
.vagrant/
.sconsign.dblite
.svn/
.DS_Store
*.swp
profile
DerivedData/
build/
GeneratedPluginRegistrant.h
GeneratedPluginRegistrant.m
.generated/
*.pbxuser
*.mode1v3
*.mode2v3
*.perspectivev3
!default.pbxuser
!default.mode1v3
!default.mode2v3
!default.perspectivev3
xcuserdata
*.moved-aside
*.pyc
*sync/
Icon?
.tags*
/Flutter/Generated.xcconfig
/Flutter/flutter_export_environment.sh

View file

@ -0,0 +1,4 @@
#import <Flutter/Flutter.h>
@interface FlutterSodiumPlugin : NSObject<FlutterPlugin>
@end

View file

@ -0,0 +1,6 @@
#import "FlutterSodiumPlugin.h"
@implementation FlutterSodiumPlugin
+ (void)registerWithRegistrar:(NSObject<FlutterPluginRegistrar>*)registrar {
}
@end

View file

@ -0,0 +1,26 @@
#
# To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html.
# Run `pod lib lint flutter_sodium.podspec' to validate before publishing.
#
Pod::Spec.new do |s|
s.name = 'flutter_sodium'
s.version = '0.0.1'
s.summary = 'A new flutter plugin project.'
s.description = <<-DESC
A new flutter plugin project.
DESC
s.homepage = 'http://example.com'
s.license = { :file => '../LICENSE' }
s.author = { 'Your Company' => 'email@example.com' }
s.source = { :path => '.' }
s.public_header_files = 'Classes**/*.h'
s.source_files = 'Classes/**/*'
s.vendored_libraries = "**/*.a"
s.dependency 'Flutter'
s.platform = :ios, '8.0'
# Flutter.framework does not contain a i386 slice. Only x86_64 simulators are supported.
s.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES', 'VALID_ARCHS[sdk=iphonesimulator*]' => 'x86_64' }
s.swift_version = '5.0'
s.xcconfig = { 'OTHER_LDFLAGS' => '-force_load "${PODS_ROOT}/../.symlinks/plugins/flutter_sodium/ios/libsodium.a"'}
end

Binary file not shown.

View file

@ -0,0 +1,25 @@
library flutter_sodium;
export 'src/cha_cha20_poly1305_ietf.dart';
export 'src/cha_cha20_poly1305.dart';
export 'src/crypto_auth.dart';
export 'src/crypto_box.dart';
export 'src/crypto_sign.dart';
export 'src/crypto_stream.dart';
export 'src/detached_cipher.dart';
export 'src/generic_hash.dart';
export 'src/hash.dart';
export 'src/key_derivation.dart';
export 'src/key_exchange.dart';
export 'src/key_pair.dart';
export 'src/onetime_auth.dart';
export 'src/password_hash.dart';
export 'src/random_bytes.dart';
export 'src/scalar_mult.dart';
export 'src/secret_box.dart';
export 'src/sealed_box.dart';
export 'src/session_keys.dart';
export 'src/short_hash.dart';
export 'src/sodium.dart';
export 'src/sodium_exception.dart';
export 'src/x_cha_cha20_poly1305_ietf.dart';

View file

@ -0,0 +1,128 @@
import 'dart:ffi';
import 'libsodium.dart';
// ignore_for_file: non_constant_identifier_names
class CryptoAeadBindings {
final String name;
final int Function() keybytes;
final int Function() nsecbytes;
final int Function() npubbytes;
final int Function() abytes;
final int Function() messagebytes_max;
final int Function(
Pointer<Uint8> c,
Pointer<Uint64> clen_p,
Pointer<Uint8> m,
int mlen,
Pointer<Uint8> ad,
int adlen,
Pointer<Uint8> nsec,
Pointer<Uint8> npub,
Pointer<Uint8> k) encrypt;
final int Function(
Pointer<Uint8> m,
Pointer<Uint64> mlen_p,
Pointer<Uint8> nsec,
Pointer<Uint8> c,
int clen,
Pointer<Uint8> ad,
int adlen,
Pointer<Uint8> npub,
Pointer<Uint8> k) decrypt;
final int Function(
Pointer<Uint8> c,
Pointer<Uint8> mac,
Pointer<Uint64> maclen_p,
Pointer<Uint8> m,
int mlen,
Pointer<Uint8> ad,
int adlen,
Pointer<Uint8> nsec,
Pointer<Uint8> npub,
Pointer<Uint8> k) encrypt_detached;
final int Function(
Pointer<Uint8> m,
Pointer<Uint8> nsec,
Pointer<Uint8> c,
int clen,
Pointer<Uint8> mac,
Pointer<Uint8> ad,
int adlen,
Pointer<Uint8> npub,
Pointer<Uint8> k) decrypt_detached;
final void Function(Pointer<Uint8> k) keygen;
CryptoAeadBindings(this.name)
: keybytes = libsodium.lookupSizet('${name}_keybytes'),
nsecbytes = libsodium.lookupSizet('${name}_nsecbytes'),
npubbytes = libsodium.lookupSizet('${name}_npubbytes'),
abytes = libsodium.lookupSizet('${name}_abytes'),
messagebytes_max = libsodium.lookupSizet('${name}_messagebytes_max'),
encrypt = libsodium
.lookup<
NativeFunction<
Int32 Function(
Pointer<Uint8>,
Pointer<Uint64>,
Pointer<Uint8>,
Uint64,
Pointer<Uint8>,
Uint64,
Pointer<Uint8>,
Pointer<Uint8>,
Pointer<Uint8>)>>('${name}_encrypt')
.asFunction(),
decrypt = libsodium
.lookup<
NativeFunction<
Int32 Function(
Pointer<Uint8>,
Pointer<Uint64>,
Pointer<Uint8>,
Pointer<Uint8>,
Uint64,
Pointer<Uint8>,
Uint64,
Pointer<Uint8>,
Pointer<Uint8>)>>('${name}_decrypt')
.asFunction(),
encrypt_detached = libsodium
.lookup<
NativeFunction<
Int32 Function(
Pointer<Uint8>,
Pointer<Uint8>,
Pointer<Uint64>,
Pointer<Uint8>,
Uint64,
Pointer<Uint8>,
Uint64,
Pointer<Uint8>,
Pointer<Uint8>,
Pointer<Uint8>)>>('${name}_encrypt_detached')
.asFunction(),
decrypt_detached = libsodium
.lookup<
NativeFunction<
Int32 Function(
Pointer<Uint8>,
Pointer<Uint8>,
Pointer<Uint8>,
Uint64,
Pointer<Uint8>,
Pointer<Uint8>,
Uint64,
Pointer<Uint8>,
Pointer<Uint8>)>>('${name}_decrypt_detached')
.asFunction(),
keygen = libsodium
.lookup<NativeFunction<Void Function(Pointer<Uint8>)>>(
'${name}_keygen')
.asFunction();
}

View file

@ -0,0 +1,40 @@
import 'dart:ffi';
import 'package:ffi/ffi.dart';
import 'libsodium.dart';
// ignore_for_file: non_constant_identifier_names
class CryptoAuthBindings {
final int Function() crypto_auth_bytes =
libsodium.lookupSizet('crypto_auth_bytes');
final int Function() crypto_auth_keybytes =
libsodium.lookupSizet('crypto_auth_keybytes');
final Pointer<Utf8> Function() crypto_auth_primitive = libsodium
.lookup<NativeFunction<Pointer<Utf8> Function()>>('crypto_auth_primitive')
.asFunction();
final int Function(
Pointer<Uint8> out, Pointer<Uint8> i, int inlen, Pointer<Uint8> k)
crypto_auth = libsodium
.lookup<
NativeFunction<
Int32 Function(Pointer<Uint8>, Pointer<Uint8>, Uint64,
Pointer<Uint8>)>>('crypto_auth')
.asFunction();
final int Function(
Pointer<Uint8> h, Pointer<Uint8> i, int inlen, Pointer<Uint8> k)
crypto_auth_verify = libsodium
.lookup<
NativeFunction<
Int32 Function(Pointer<Uint8>, Pointer<Uint8>, Uint64,
Pointer<Uint8>)>>('crypto_auth_verify')
.asFunction();
final void Function(Pointer<Uint8> k) crypto_auth_keygen = libsodium
.lookup<NativeFunction<Void Function(Pointer<Uint8>)>>(
'crypto_auth_keygen')
.asFunction();
}

View file

@ -0,0 +1,189 @@
import 'dart:ffi';
import 'package:ffi/ffi.dart';
import 'libsodium.dart';
// ignore_for_file: non_constant_identifier_names
class CryptoBoxBindings {
final int Function() crypto_box_seedbytes =
libsodium.lookupSizet('crypto_box_seedbytes');
final int Function() crypto_box_publickeybytes =
libsodium.lookupSizet('crypto_box_publickeybytes');
final int Function() crypto_box_secretkeybytes =
libsodium.lookupSizet('crypto_box_secretkeybytes');
final int Function() crypto_box_noncebytes =
libsodium.lookupSizet('crypto_box_noncebytes');
final int Function() crypto_box_macbytes =
libsodium.lookupSizet('crypto_box_macbytes');
final int Function() crypto_box_messagebytes_max =
libsodium.lookupSizet('crypto_box_messagebytes_max');
final int Function() crypto_box_sealbytes =
libsodium.lookupSizet('crypto_box_sealbytes');
final int Function() crypto_box_beforenmbytes =
libsodium.lookupSizet('crypto_box_beforenmbytes');
final Pointer<Utf8> Function() crypto_box_primitive = libsodium
.lookup<NativeFunction<Pointer<Utf8> Function()>>('crypto_box_primitive')
.asFunction();
final int Function(Pointer<Uint8> pk, Pointer<Uint8> sk, Pointer<Uint8> seed)
crypto_box_seed_keypair = libsodium
.lookup<
NativeFunction<
Int32 Function(Pointer<Uint8>, Pointer<Uint8>,
Pointer<Uint8>)>>('crypto_box_seed_keypair')
.asFunction();
final int Function(
Pointer<Uint8> pk,
Pointer<Uint8>
sk) crypto_box_keypair = libsodium
.lookup<NativeFunction<Int32 Function(Pointer<Uint8>, Pointer<Uint8>)>>(
'crypto_box_keypair')
.asFunction();
final int Function(Pointer<Uint8> c, Pointer<Uint8> m, int mlen,
Pointer<Uint8> n, Pointer<Uint8> pk, Pointer<Uint8> sk)
crypto_box_easy = libsodium
.lookup<
NativeFunction<
Int32 Function(
Pointer<Uint8>,
Pointer<Uint8>,
Uint64,
Pointer<Uint8>,
Pointer<Uint8>,
Pointer<Uint8>)>>('crypto_box_easy')
.asFunction();
final int Function(Pointer<Uint8> m, Pointer<Uint8> c, int clen,
Pointer<Uint8> n, Pointer<Uint8> pk, Pointer<Uint8> sk)
crypto_box_open_easy = libsodium
.lookup<
NativeFunction<
Int32 Function(
Pointer<Uint8>,
Pointer<Uint8>,
Uint64,
Pointer<Uint8>,
Pointer<Uint8>,
Pointer<Uint8>)>>('crypto_box_open_easy')
.asFunction();
final int Function(Pointer<Uint8> c, Pointer<Uint8> mac, Pointer<Uint8> m,
int mlen, Pointer<Uint8> n, Pointer<Uint8> pk, Pointer<Uint8> sk)
crypto_box_detached = libsodium
.lookup<
NativeFunction<
Int32 Function(
Pointer<Uint8>,
Pointer<Uint8>,
Pointer<Uint8>,
Uint64,
Pointer<Uint8>,
Pointer<Uint8>,
Pointer<Uint8>)>>('crypto_box_detached')
.asFunction();
final int Function(Pointer<Uint8> m, Pointer<Uint8> c, Pointer<Uint8> mac,
int clen, Pointer<Uint8> n, Pointer<Uint8> pk, Pointer<Uint8> sk)
crypto_box_open_detached = libsodium
.lookup<
NativeFunction<
Int32 Function(
Pointer<Uint8>,
Pointer<Uint8>,
Pointer<Uint8>,
Uint64,
Pointer<Uint8>,
Pointer<Uint8>,
Pointer<Uint8>)>>('crypto_box_open_detached')
.asFunction();
final int Function(
Pointer<Uint8> c, Pointer<Uint8> m, int mlen, Pointer<Uint8> pk)
crypto_box_seal = libsodium
.lookup<
NativeFunction<
Int32 Function(Pointer<Uint8>, Pointer<Uint8>, Uint64,
Pointer<Uint8>)>>('crypto_box_seal')
.asFunction();
final int Function(Pointer<Uint8> m, Pointer<Uint8> c, int clen,
Pointer<Uint8> pk, Pointer<Uint8> sk) crypto_box_seal_open =
libsodium
.lookup<
NativeFunction<
Int32 Function(Pointer<Uint8>, Pointer<Uint8>, Uint64,
Pointer<Uint8>, Pointer<Uint8>)>>('crypto_box_seal_open')
.asFunction();
final int Function(Pointer<Uint8> k, Pointer<Uint8> pk, Pointer<Uint8> sk)
crypto_box_beforenm = libsodium
.lookup<
NativeFunction<
Int32 Function(Pointer<Uint8>, Pointer<Uint8>,
Pointer<Uint8>)>>('crypto_box_beforenm')
.asFunction();
final int Function(Pointer<Uint8> c, Pointer<Uint8> m, int mlen,
Pointer<Uint8> n, Pointer<Uint8> k) crypto_box_easy_afternm =
libsodium
.lookup<
NativeFunction<
Int32 Function(
Pointer<Uint8>,
Pointer<Uint8>,
Uint64,
Pointer<Uint8>,
Pointer<Uint8>)>>('crypto_box_easy_afternm')
.asFunction();
final int Function(Pointer<Uint8> m, Pointer<Uint8> c, int clen,
Pointer<Uint8> n, Pointer<Uint8> k) crypto_box_open_easy_afternm =
libsodium
.lookup<
NativeFunction<
Int32 Function(
Pointer<Uint8>,
Pointer<Uint8>,
Uint64,
Pointer<Uint8>,
Pointer<Uint8>)>>('crypto_box_open_easy_afternm')
.asFunction();
final int Function(Pointer<Uint8> c, Pointer<Uint8> mac, Pointer<Uint8> m,
int mlen, Pointer<Uint8> n, Pointer<Uint8> k)
crypto_box_detached_afternm = libsodium
.lookup<
NativeFunction<
Int32 Function(
Pointer<Uint8>,
Pointer<Uint8>,
Pointer<Uint8>,
Uint64,
Pointer<Uint8>,
Pointer<Uint8>)>>('crypto_box_detached_afternm')
.asFunction();
final int Function(Pointer<Uint8> m, Pointer<Uint8> c, Pointer<Uint8> mac,
int clen, Pointer<Uint8> n, Pointer<Uint8> k)
crypto_box_open_detached_afternm = libsodium
.lookup<
NativeFunction<
Int32 Function(
Pointer<Uint8>,
Pointer<Uint8>,
Pointer<Uint8>,
Uint64,
Pointer<Uint8>,
Pointer<Uint8>)>>('crypto_box_open_detached_afternm')
.asFunction();
}

View file

@ -0,0 +1,48 @@
import 'dart:ffi';
import 'libsodium.dart';
// ignore_for_file: non_constant_identifier_names
class CryptoCoreBindings {
final int Function() crypto_core_hchacha20_outputbytes =
libsodium.lookupSizet('crypto_core_hchacha20_outputbytes');
final int Function() crypto_core_hchacha20_inputbytes =
libsodium.lookupSizet('crypto_core_hchacha20_inputbytes');
final int Function() crypto_core_hchacha20_keybytes =
libsodium.lookupSizet('crypto_core_hchacha20_keybytes');
final int Function() crypto_core_hchacha20_constbytes =
libsodium.lookupSizet('crypto_core_hchacha20_constbytes');
final int Function(Pointer<Uint8> out, Pointer<Uint8> in_, Pointer<Uint8> k,
Pointer<Uint8> c) crypto_core_hchacha20 =
libsodium
.lookup<
NativeFunction<
Int32 Function(Pointer<Uint8>, Pointer<Uint8>, Pointer<Uint8>,
Pointer<Uint8>)>>('crypto_core_hchacha20')
.asFunction();
final int Function() crypto_core_hsalsa20_outputbytes =
libsodium.lookupSizet('crypto_core_hsalsa20_outputbytes');
final int Function() crypto_core_hsalsa20_inputbytes =
libsodium.lookupSizet('crypto_core_hsalsa20_inputbytes');
final int Function() crypto_core_hsalsa20_keybytes =
libsodium.lookupSizet('crypto_core_hsalsa20_keybytes');
final int Function() crypto_core_hsalsa20_constbytes =
libsodium.lookupSizet('crypto_core_hsalsa20_constbytes');
final int Function(Pointer<Uint8> out, Pointer<Uint8> in_, Pointer<Uint8> k,
Pointer<Uint8> c) crypto_core_hsalsa20 =
libsodium
.lookup<
NativeFunction<
Int32 Function(Pointer<Uint8>, Pointer<Uint8>, Pointer<Uint8>,
Pointer<Uint8>)>>('crypto_core_hsalsa20')
.asFunction();
}

View file

@ -0,0 +1,78 @@
import 'dart:ffi';
import 'package:ffi/ffi.dart';
import 'libsodium.dart';
// ignore_for_file: non_constant_identifier_names
class CryptoGenerichashBindings {
final int Function() crypto_generichash_bytes_min =
libsodium.lookupSizet('crypto_generichash_bytes_min');
final int Function() crypto_generichash_bytes_max =
libsodium.lookupSizet('crypto_generichash_bytes_max');
final int Function() crypto_generichash_bytes =
libsodium.lookupSizet('crypto_generichash_bytes');
final int Function() crypto_generichash_keybytes_min =
libsodium.lookupSizet('crypto_generichash_keybytes_min');
final int Function() crypto_generichash_keybytes_max =
libsodium.lookupSizet('crypto_generichash_keybytes_max');
final int Function() crypto_generichash_keybytes =
libsodium.lookupSizet('crypto_generichash_keybytes');
final Pointer<Utf8> Function() crypto_generichash_primitive = libsodium
.lookup<NativeFunction<Pointer<Utf8> Function()>>(
'crypto_generichash_primitive')
.asFunction();
final int Function() crypto_generichash_statebytes =
libsodium.lookupSizet('crypto_generichash_statebytes');
final int Function(Pointer<Uint8> out, int outlen, Pointer<Uint8> i,
int inlen, Pointer<Uint8> key, int keylen) crypto_generichash =
libsodium
.lookup<
NativeFunction<
Int32 Function(Pointer<Uint8>, IntPtr, Pointer<Uint8>, Uint64,
Pointer<Uint8>, IntPtr)>>('crypto_generichash')
.asFunction();
final int Function(
Pointer<Uint8> state, Pointer<Uint8> key, int keylen, int outlen)
crypto_generichash_init = libsodium
.lookup<
NativeFunction<
Int32 Function(Pointer<Uint8>, Pointer<Uint8>, IntPtr,
IntPtr)>>('crypto_generichash_init')
.asFunction();
final int Function(Pointer<Uint8> state, Pointer<Uint8> i, int inlen)
crypto_generichash_update = libsodium
.lookup<
NativeFunction<
Int32 Function(
Pointer<Uint8>,
Pointer<Uint8>,
Uint64,
)>>('crypto_generichash_update')
.asFunction();
final int Function(Pointer<Uint8> state, Pointer<Uint8> out, int outlen)
crypto_generichash_final = libsodium
.lookup<
NativeFunction<
Int32 Function(
Pointer<Uint8>,
Pointer<Uint8>,
IntPtr,
)>>('crypto_generichash_final')
.asFunction();
final void Function(Pointer<Uint8> k) crypto_generichash_keygen = libsodium
.lookup<NativeFunction<Void Function(Pointer<Uint8>)>>(
'crypto_generichash_keygen')
.asFunction();
}

View file

@ -0,0 +1,26 @@
import 'dart:ffi';
import 'package:ffi/ffi.dart';
import 'libsodium.dart';
// ignore_for_file: non_constant_identifier_names
class CryptoHashBindings {
final String name;
final int Function() bytes;
final Pointer<Utf8> Function() primitive;
final int Function(Pointer<Uint8> out, Pointer<Uint8> i, int inlen) hash;
CryptoHashBindings(this.name)
: bytes = libsodium.lookupSizet('${name}_bytes'),
primitive = libsodium
.lookup<NativeFunction<Pointer<Utf8> Function()>>(
'${name}_primitive')
.asFunction(),
hash = libsodium
.lookup<
NativeFunction<
Int32 Function(
Pointer<Uint8>, Pointer<Uint8>, Uint64)>>(name)
.asFunction();
}

View file

@ -0,0 +1,37 @@
import 'dart:ffi';
import 'package:ffi/ffi.dart';
import 'libsodium.dart';
// ignore_for_file: non_constant_identifier_names
class CryptoKdfBindings {
final int Function() crypto_kdf_bytes_min =
libsodium.lookupSizet('crypto_kdf_bytes_min');
final int Function() crypto_kdf_bytes_max =
libsodium.lookupSizet('crypto_kdf_bytes_max');
final int Function() crypto_kdf_contextbytes =
libsodium.lookupSizet('crypto_kdf_contextbytes');
final int Function() crypto_kdf_keybytes =
libsodium.lookupSizet('crypto_kdf_keybytes');
final Pointer<Utf8> Function() crypto_kdf_primitive = libsodium
.lookup<NativeFunction<Pointer<Utf8> Function()>>('crypto_kdf_primitive')
.asFunction();
final int Function(Pointer<Uint8> subkey, int subkey_len, int subkey_id,
Pointer<Uint8> ctx, Pointer<Uint8> key) crypto_kdf_derive_from_key =
libsodium
.lookup<
NativeFunction<
Int32 Function(Pointer<Uint8>, IntPtr, Uint64, Pointer<Uint8>,
Pointer<Uint8>)>>('crypto_kdf_derive_from_key')
.asFunction();
final void Function(Pointer<Uint8> k) crypto_kdf_keygen = libsodium
.lookup<NativeFunction<Void Function(Pointer<Uint8>)>>(
'crypto_kdf_keygen')
.asFunction();
}

View file

@ -0,0 +1,73 @@
import 'dart:ffi';
import 'package:ffi/ffi.dart';
import 'libsodium.dart';
// ignore_for_file: non_constant_identifier_names
class CryptoKxBindings {
final int Function() crypto_kx_publickeybytes =
libsodium.lookupSizet('crypto_kx_publickeybytes');
final int Function() crypto_kx_secretkeybytes =
libsodium.lookupSizet('crypto_kx_secretkeybytes');
final int Function() crypto_kx_seedbytes =
libsodium.lookupSizet('crypto_kx_seedbytes');
final int Function() crypto_kx_sessionkeybytes =
libsodium.lookupSizet('crypto_kx_sessionkeybytes');
final Pointer<Utf8> Function() crypto_kx_primitive = libsodium
.lookup<NativeFunction<Pointer<Utf8> Function()>>('crypto_kx_primitive')
.asFunction();
final int Function(Pointer<Uint8> pk, Pointer<Uint8> sk, Pointer<Uint8> seed)
crypto_kx_seed_keypair = libsodium
.lookup<
NativeFunction<
Int32 Function(Pointer<Uint8>, Pointer<Uint8>,
Pointer<Uint8>)>>('crypto_kx_seed_keypair')
.asFunction();
final int Function(
Pointer<Uint8> pk,
Pointer<Uint8>
sk) crypto_kx_keypair = libsodium
.lookup<NativeFunction<Int32 Function(Pointer<Uint8>, Pointer<Uint8>)>>(
'crypto_kx_keypair')
.asFunction();
final int Function(
Pointer<Uint8> rx,
Pointer<Uint8> tx,
Pointer<Uint8> client_pk,
Pointer<Uint8> client_sk,
Pointer<Uint8> server_pk) crypto_kx_client_session_keys =
libsodium
.lookup<
NativeFunction<
Int32 Function(
Pointer<Uint8>,
Pointer<Uint8>,
Pointer<Uint8>,
Pointer<Uint8>,
Pointer<Uint8>)>>('crypto_kx_client_session_keys')
.asFunction();
final int Function(
Pointer<Uint8> rx,
Pointer<Uint8> tx,
Pointer<Uint8> server_pk,
Pointer<Uint8> server_sk,
Pointer<Uint8> client_pk) crypto_kx_server_session_keys =
libsodium
.lookup<
NativeFunction<
Int32 Function(
Pointer<Uint8>,
Pointer<Uint8>,
Pointer<Uint8>,
Pointer<Uint8>,
Pointer<Uint8>)>>('crypto_kx_server_session_keys')
.asFunction();
}

View file

@ -0,0 +1,68 @@
import 'dart:ffi';
import 'package:ffi/ffi.dart';
import 'libsodium.dart';
// ignore_for_file: non_constant_identifier_names
class CryptoOnetimeauthBindings {
final int Function() crypto_onetimeauth_statebytes =
libsodium.lookupSizet('crypto_onetimeauth_statebytes');
final int Function() crypto_onetimeauth_bytes =
libsodium.lookupSizet('crypto_onetimeauth_bytes');
final int Function() crypto_onetimeauth_keybytes =
libsodium.lookupSizet('crypto_onetimeauth_keybytes');
final Pointer<Utf8> Function() crypto_onetimeauth_primitive = libsodium
.lookup<NativeFunction<Pointer<Utf8> Function()>>(
'crypto_onetimeauth_primitive')
.asFunction();
final int Function(
Pointer<Uint8> out, Pointer<Uint8> i, int inlen, Pointer<Uint8> k)
crypto_onetimeauth = libsodium
.lookup<
NativeFunction<
Int32 Function(Pointer<Uint8>, Pointer<Uint8>, Uint64,
Pointer<Uint8>)>>('crypto_onetimeauth')
.asFunction();
final int Function(
Pointer<Uint8> h, Pointer<Uint8> i, int inlen, Pointer<Uint8> k)
crypto_onetimeauth_verify = libsodium
.lookup<
NativeFunction<
Int32 Function(Pointer<Uint8>, Pointer<Uint8>, Uint64,
Pointer<Uint8>)>>('crypto_onetimeauth_verify')
.asFunction();
final int Function(
Pointer<Uint8> state,
Pointer<Uint8>
key) crypto_onetimeauth_init = libsodium
.lookup<NativeFunction<Int32 Function(Pointer<Uint8>, Pointer<Uint8>)>>(
'crypto_onetimeauth_init')
.asFunction();
final int Function(Pointer<Uint8> state, Pointer<Uint8> i, int inlen)
crypto_onetimeauth_update = libsodium
.lookup<
NativeFunction<
Int32 Function(Pointer<Uint8>, Pointer<Uint8>,
Uint64)>>('crypto_onetimeauth_update')
.asFunction();
final int Function(
Pointer<Uint8> state,
Pointer<Uint8>
out) crypto_onetimeauth_final = libsodium
.lookup<NativeFunction<Int32 Function(Pointer<Uint8>, Pointer<Uint8>)>>(
'crypto_onetimeauth_final')
.asFunction();
final void Function(Pointer<Uint8> k) crypto_onetimeauth_keygen = libsodium
.lookup<NativeFunction<Void Function(Pointer<Uint8>)>>(
'crypto_onetimeauth_keygen')
.asFunction();
}

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